質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Haml

Haml(HTML abstraction markup language)は、HTML/XHTMLを効率的に記述するためのマークアップ言語および記法です。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Q&A

1回答

1181閲覧

新規投稿にセレクトボックスを用いて、カテゴリー機能を実装したい

susume

総合スコア13

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Haml

Haml(HTML abstraction markup language)は、HTML/XHTMLを効率的に記述するためのマークアップ言語および記法です。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

0グッド

0クリップ

投稿2020/08/26 05:45

編集2020/08/31 14:08

前提・実現したいこと

新規投稿をするときに、セレクトボックスを用いて、カテゴリー機能を実装したいです。

##状況
railsで個人アプリを開発中で、スノボー版インスタグラムを作成しています。

現在の状況としては、投稿機能はカテゴリー以外は実装されています。
(image,text,titleなど)

また、中間テーブルであるpost_categoryテーブルの紐付けがうまく行っていないのか、新規投稿される時にpost_idとcategory_idはデータベースに登録されずです。

以下がビューの画像です。
イメージ説明

該当のソースコード

posts/new.html.haml

ruby

1- if @post.errors.any? 2 .alert 3 %ul 4 - @post.errors.full_messages.each do |message| 5 %li= message 6 7#account-page.account-page 8 .account-page__inner.clearfix 9 .post-new-edit-page 10 = render partial: 'form'

_form.html.haml

= form_for(@post) do |f| .field .field-label = f.label :title, "snowB" .field-input = f.text_field :title .field .field-label = f.label :body, "ココがポイント!" .field-input = f.text_area :body .field .field-label = f.label :image, "snowB写真" .field-input = f.attachment_field :image .field .field-label = f.label :category, "カテゴリーを選択してください" .field-input = f.select :category_ids, options_for_select( @category_parent_array.map{|c| [c, {}]}), {}, {class: "parent_select", id: "parent_category"} .actions = f.submit "投稿する", class: "btn"

posts_cotllor.rb

class PostsController < ApplicationController before_action :authenticate_user!, except: [:index] before_action :set_category, only:[:new, :create] def index @posts = Post.all @category_parent_array = Category.where(ancestry: nil) end def show @post = Post.find(params[:id]) @comment = Comment.new @comments = @post.comments.includes(:user) end def new @post = Post.new end def get_category_children @category_children = Category.find("#{params[parent_id]}").children end def create @post = Post.new(post_params) @post.user_id = current_user.id if @post.save redirect_to post_path(@post), notice: '投稿されました' else render :new, alert: '投稿できませんでした' end end def edit @post = Post.find(params[:id]) if @post.user != current_user redirect_to posts_path, alert: '不正なアクセスです' end end def update @post = Post.find(params[:id]) if @post.update(post_params) redirect_to post_path(@post), notice: '投稿が更新されました' else render :edit end end def destroy post = Post.find(params[:id]) post.destroy redirect_to posts_path end private def post_params params.require(:post).permit(:title, :body, :image, { post_categories: {} }) end def set_category @category_parent_array = [] Category.where(ancestry: nil).each do |parent| @category_parent_array << parent.name end end end

mysqlのデータベース関連
イメージ説明
イメージ説明
イメージ説明

##アソシエーション
post.rb

class Post < ApplicationRecord belongs_to :user attachment :image has_many :favorites, dependent: :destroy has_many :comments with_options presence: true do validates :title validates :body validates :image end has_many :post_categories, dependent: :destroy has_many :categories, through: :post_categories accepts_nested_attributes_for :categories, allow_destroy: true end

category.rb

class Category < ApplicationRecord has_ancestry has_many :post_categories, dependent: :destroy has_many :posts, through: :post_categories end

post_category.rb

class PostCategory < ApplicationRecord belongs_to :post belongs_to :category end

db/seeds.rb

snowboard = Category.create(name: "スノーボード") snowboard_1 = snowboard.children.create([ {name: "BURTON"}, {name: "K2"}, {name: "SALOMON"}]) snowboots = Category.create(name: "ブーツ") snowboots_1 = snowboots.children.create([ {name: "BURTON"}, {name: "DEELUXE"}, {name: "FLUX"}])

足りない情報があれば教えてください。

なんでカテゴリーが登録されないんでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

winterboum

2020/08/27 00:07

関連定義ではcategoryなのにviewでは親子が顔を出します。 関連との関係がわからない。
susume

2020/08/27 12:24

関連との関係が分からないとのことですが、私は的確な回答をもらうためにどのような情報を追記すればよろしいでしょうか?
winterboum

2020/08/27 12:42 編集

_category.html.haml の -@parent_categories. @default_child_categories はどこから来てますか? PostCategory の belongs_to :category と parent_categories. child_categories はどういう関係にありますか PostCategory の category_id には _category.html.haml のどの要素の値を入れますか
susume

2020/08/27 15:50

回答いたします。 >>_category.html.haml の -@parent_categories. @default_child_categories はどこから来てますか? →postsコントローラーからきています。質問内容に追記いたしました。 >>PostCategory の belongs_to :category と parent_categories. child_categories はどういう関係にありますか →モデルやアソシエーションはどうなっているかという質問でしょうか? それならば、parent_categories. child_categoriesのモデルは作成しておりませんし、アソシエーションもありません。 理由は、gem ancestryでカテゴリーを階層構造にしているので、その必要はないと判断したからです。 >>PostCategory の category_id には _category.html.haml のどの要素の値を入れますか →db/fixtures/01_categoryにあるデータです。 seed-fuを導入し、質問にあるようにカテゴリーはデータベースに登録されています。 _category.html.hamlどの要素の値かについては、 value:"parent"にはpararents.categoriesの値を、childrenにはchildrenの値を入れたいです。 01_category.rbのparents =で定義されているのがvalue:parentで取得したいもの、〇〇_childで定義されているのが、childrenで取得したい値となります。
winterboum

2020/08/27 22:42

>>PostCategory の category_id には _category.html.haml のどの要素の値を入れますか この質問はDBのはなしではなく、viewのどの要素か、を聞いてます
susume

2020/08/27 23:00

>>この質問はDBのはなしではなく、viewのどの要素か、を聞いてます →%option{value: "parent"},%option{value: "children"}の要素を入れたいです
guest

回答1

0

この質問はDBのはなしではなく、viewのどの要素か、を聞いてます

→%option{value: "parent"},%option{value: "children"}の要素を入れたいです

まあそうだろうなぁ、とは予想はついていたのですが、わざわざ質問を繰り返したのは _category.html.haml がそういうことを少しも匂わせてすら居ないからで、そこに気づいて欲しかったからです。
先は長いです。

まず、_category.html.haml のselectはどれを選んでも値は皆 value: "children"で同じです。ここは c.idを渡す所。
ただ、ここにoptionをずらずら記述するのはやめたほうが良いです。
select と options_for_select を使って書くのが良いと思います。

関連の値を入力するfieldをviewに書くにはfields_forを参照してください。
これを使わなくても selectにname属性を定義しておけばなんとかはなりますが。

投稿2020/08/27 23:30

winterboum

総合スコア23364

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

susume

2020/08/28 10:16

ご回答いただきましてありがとうございます。 一旦ご教示いただいたoptions_for_selectを使って実装試みてみますね! ちなみにこのコードについては以下の記事を参考にしており、以下の記事には_category.hrml,hamlのoptionタグにvalue:"<%=c.id %>"とあるので、このように書けばもしかして解決したりするんでしょうか? ※ただ、value:"<%=c.id %>"の部分がhamlでどう記述すればいいのか分からず、構文エラーが出てしまうので一回断念してvalue:parentとかにした経緯があります。 https://qiita.com/kenzoukenzou104809/items/07f6b5f7fdcf2761ac8f いずれにせよ、ヒアリングしていただいた上でご提案いただいたので、また実装で困ったことがあればご相談させていただきます。
winterboum

2020/08/28 11:45

その記事は、selectのoptionを動的に変える というところしかしていません。 kamkamoさんのシステムが動くようになるには、その他に 多対多の関連を入力するview、 それを受ける controller を実装する必要があります
susume

2020/08/28 14:54

なるほど!そうだったんですね。 ご確認いただきましてありがとうございます。 ちょっと試行錯誤してみますね。
susume

2020/08/30 07:37

>>まず、_category.html.haml のselectはどれを選んでも値は皆 value: "children"で同じです。ここは c.idを渡す所。 ただ、ここにoptionをずらずら記述するのはやめたほうが良いです。 select と options_for_select を使って書くのが良いと思います。 関連の値を入力するfieldをviewに書くにはfields_forを参照してください。 これを使わなくても selectにname属性を定義しておけばなんとかはなりますが。 →options_for_select、field_forを使ってコード書いてみました。 参考記事にあるようにmapメソッドも使ってみたのですが、質問の追記にあるようにエラー発生しました。 これってoptions_for_selectの書き方など間違っていますかね?? 2日ぐらい様々な記事をみて書き方学んでみましたが、自分の調べる力が 限界で実現したいカテゴリー機能の実装がなかなかできません。 今回の内容を解決するためには、どんなコードを書けばいいのかヒントをいただけないでしょうか?
winterboum

2020/08/30 12:36

多対多の実装 で検索してみてください
susume

2020/08/30 14:53

多対多の実装で検索し、サンプルみてみました。 内容をもとに新規投稿する時にカテゴリー機能も付与されているかどうか実験的に確認してみました。 (中間テーブルであるpost_categoryテーブルにデータベースにデータが登録されるか) しかし、質問内容なあるように、新規投稿してもカテゴリー情報だけ反映されません。 ※中間テーブルにpost_idとcategory_idが本来は登録されるはずだが、データベースに反映されない このような場合、どんな原因が考えられますか? ※アソシエーションは多分あっていると思うので、postコントローラーと_form.html.hamlにあるoptions_for_select部分のコードの書き方が間違っていると予想しています。
winterboum

2020/08/30 20:54

最新のcodeを載せてください。 model,controller,view全部
susume

2020/08/30 23:51

こちら全て最新のコードに変更いたしました。
winterboum

2020/08/31 00:15

「多対多の実装で検索し、サンプルみてみました。」 とは どれを参考にしました?
susume

2020/08/31 09:50

以下の記事をみて、中間テーブルやモデルのアソシエーションの組み方を主にみました。 https://qiita.com/tanutanu/items/1607627d475072701247 コントローラーにも params.require(:work).permit(:name, :description, { category_ids: [] })を参考に、 { category_ids: [] })⇦を追記しました。
winterboum

2020/08/31 10:13

いくつか落ちてます accepts_nested_attributes_for :work_categories に該当するもの ? controller最新になってない? 参照された記事のdef work_paramおかしい気がする。これで良いのかな。。 post_categories: { } にしないとだめかも。 Category の has_many :post_category は間違い options_for_select の第一引数がおかしい https://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-options_for_select
susume

2020/08/31 14:10

accepts_nested_attributes_for :work_categories →accepts_nested_attributes_for :categories, allow_destroy: trueと記述いたしました。 controller最新になってない? →最新にいたしました post_categories: { } →コントローラーをご確認ください。 ※もしかしたらまた書き方間違っているので、どのように変更するべきかご指摘ください。 Category の has_many :post_category →Category の has_many :post_categoriesと複数形に変更いたしました options_for_select の第一引数がおかしい →そのようにおかしいのでしょうか?具体的なコードにてご教示いただけると幸いです。
winterboum

2020/08/31 22:34

post_params の最後おかしい options_for_select の第一引数がおかしい のあとにつけたlinkのマニュアル見てください
susume

2020/09/01 02:16

post_params の最後おかしい →どのようにおかしいのでしょうか? options_for_select の第一引数がおかしい →@people, 'id', 'name'とあるので、 @category_parent_array, 'id', 'name'と書けばいいのしょうか?
winterboum

2020/09/01 02:20

post_params の最後 {} になってる ??? @people, 'id', 'name' ってどこにあります?
susume

2020/09/01 04:42

params.require(:post).permit(:title, :body, :image, :post_categories) このように変更すればいいでしょうか? 少し下にスクロールしていただくとoptions_from_collection_for_selectの箇所があるのでそこに記載されていました。 options_for_selectには配列の書き方しか書かれていないため、@people, 'id', 'name'のことなのかな?と認識していました。 結局、 = f.select :category_ids, options_for_select( @category_parent_array.map{|c| [c, {}]}), {}, {class: "parent_select", id: "parent_category"} の書き方が解決されていないので、どのように書けばいいのか具体的にコードを教えていただければ幸いです。
winterboum

2020/09/01 07:59

options_from_collection_for_select と options_for_select は違うmethodですからごちゃまぜにしないで。 options_for_select( @category_parent_array とあるから @category_parent_array は配列なんでしょ? なら 「options_for_selectには配列の書き方しか書かれていない」でなにが問題?
susume

2020/09/01 08:58

options_from_collection_for_select と options_for_select は違うmethodですからごちゃまぜにしないで。 →承知いたしました。 options_for_select( @category_parent_array とあるから @category_parent_array は配列なんでしょ? なら 「options_for_selectには配列の書き方しか書かれていない」でなにが問題? →それでは配列で書くべきという認識ですね。かしこまりました。 ちなみに、配列で書くとなると、実際にはかなりの分量になるので冗長になるかなと思いました。 結局、= f.select :category_ids, options_for_select( @category_parent_array.map{|c| [c, {}]}), {}, {class: "parent_select", id: "parent_category"}のコードは、どのように書けばいいのでしょうか?? 参考記事にあるのように = f.select :category_ids, options_for_select(["snowboard", "スノーボード"])みたいにカテゴリー要素を全てずらずらと書くのがいいのでしょうか??
winterboum

2020/09/01 09:01

配列 が引数ということは 配列を生で書くばかりではなく、配列の入った変数を入れれば良いんですよ
susume

2020/09/01 09:32

配列の入った変数... それが@category_parent_arrayと思っているんですが、それが違うと言われているので、何が正解なのかわからない状況です.... ここでの配列のはいった変数とは何を指すのでしょうか? また、options_for_selectの部分はどのように書けばいいのでしょうか?
winterboum

2020/09/01 10:14

options_for_select( @category_parent_array.map{|c| [c, {}]}) は@category_parent_arrayでなく、@category_parent_array.map{|c| [c, {}]}が引数になってます。
susume

2020/09/01 11:44

つまり、.map{|c| [c, {}]}を削除すればいいということでしょうか?
winterboum

2020/09/01 11:48

はい。  あ、ちがうな。名前に騙された。 @category_parent_array = Category.where(ancestry: nil).pluck(:name,:id) にするのも必要ですね。
winterboum

2020/09/01 11:51

@category_parent_array = Category.where(ancestry: nil) を他で使う可能性がある場合はviewの方で @category_parent_array.pluck(:name,:id) もしくは @category_parent_array.map{|c| [c.name,c.id]}
susume

2020/09/01 15:39

ご回答いただきましてありがとうございます。 コントローラーは、 def set_category @category_parent_array = Category.where(ancestry: nil).pluck(:name, :id) end options_for_selectの部分は、 = f.select :category_ids, options_for_select(@category_parent_array.pluck(:name, :id)), {class: "parent_select", id: "parent_category"} 上記2点を変更いたしました。 ただ、no implicit conversion of Symbol into Integer というエラーが発生しました。 エラー内容を調べてみると、タイプミスや,;:などのいらないことを追記していることが原因のエラーっぽいのですが、options_for_selectのコード見る限り、どこが問題??ってなってます。
winterboum

2020/09/01 20:54

エラーメッセージにはもう少し情報があるはずです。どのfileのどの行かと
susume

2020/09/01 22:57

app/views/posts/_form.html.haml:21:in `block in _app_views_posts__form_html_haml___4296242115168899564_70246744599020' app/views/posts/_form.html.haml:1:in `_app_views_posts__form_html_haml___4296242115168899564_70246744599020' app/views/posts/new.html.haml:10:in `_app_views_posts_new_html_haml__1907597231018024451_70246744766860' こんな感じです。
winterboum

2020/09/01 23:46

で、それらの行とその前後を確認するにはどこをみたらよいですか
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問