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

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

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

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

Q&A

解決済

2回答

2000閲覧

paramsのネストされた値がストロングパラメータで取得できない

ruby_0ct

総合スコア57

Ruby on Rails

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

0グッド

1クリップ

投稿2018/03/28 17:24

編集2018/03/28 17:30

paramsからストロングパラメータを通して値を取得したいのですが、newを行った時にnilとなってしまい、ネストされた要素の値が取得できません。

商品登録を行う処理でhas_manyincludesさせた商品カテゴリーテーブルをネストしています。

カテゴリーはプルダウンメニューで選択するのですが、そのvalue(テーブルでいうところのid)が取得できません。
ストロングパラメータの書き方を色々変えてもできず、どのようにしたら、ストロングパラメータを通して取得できるのでしょうか?それとも、別の取得方法をするのでしょうか?
教えていただければ助かります。

テーブルの関係は、
productcategory 1対多 product

paramsの中身

Parameters: { "utf8"=>"✓", "authenticity_token"=>"", "product"=>{ "product_name"=>"商品名", "productcategories"=>{ "productcategory_id"=>"2" } }, "commit"=>"商品を追加する" }

取得できない要素は、カテゴリーテーブルのproductcategory_idです。

product_controller.rb

def product_params product_params = params.require(:product).permit(:id, :product_name, productcategories: [:productcategory_id]) end

モデル

product.rb

class Product < ApplicationRecord has_many :productcategories validates_associated :productcategories accepts_nested_attributes_for :productcategories end

productcategory.rb

class Productcategory < ApplicationRecord belongs_to :poduct accepts_nested_attributes_for :product end

コントローラ

def new @product = Product.new @category = Productcategory.new end def create @product = Product.new(product_params) respond_to do |format| if @product.save! format.html { redirect_to @product, notice: '商品の追加完了' } format.json { render :show, status: :created, location: @product } else format.html { redirect_to new_product_url } format.json { render json: @product.errors, status: :unprocessable_entity } end end end private def product_params product_params = params.require(:product).permit(:productname, productcategories: [:productcategory_id]) end

@productをデバッグしてみると

<Product id: 5, productname: "商品名A", productcategory_id: nil>

nilとなって取得できていません。

view

カテゴリーはプルダウンメニューから選びます。

products/new.html.erb

<%= form_for @product do |f| %> <p><%= f.text_field :productname, placeholder: '商品名を入力', autocomplete: 'off' %></p> <%= f.fields_for :productcategories do |c| %> <p><%= c.collection_select :productcategory_id, Productcategory.all, :id, :category, prompt: 'カテゴリーを選択' %></p> <% end %> <div class="formsubmit"><%= f.submit '商品を追加する' %></div> <% end %>

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

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

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

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

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

guest

回答2

0

自己解決

一から作り直しを行ったところ、解決しました。
modelの設定など細かいところで誤りがあったことが、原因でした。

投稿2018/04/10 17:48

ruby_0ct

総合スコア57

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

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

0

rb

1params.require(:product).permit(:id, :product_name, productcategories: [:productcategory_id])

で合っていると思います。

rails console で以下のように実験して確かめました。

rb

1p1 = ActionController::Parameters.new( 2 { 3 "utf8"=>"✓", 4 "authenticity_token"=>"", 5 "product"=>{ 6 "product_name"=>"商品名", 7 "productcategories"=>{ 8 "productcategory_id"=>"2" 9 } 10 }, 11 "commit"=>"商品を追加する" 12 } 13) 14 15p2 = p1.require(:product).permit(:id, :product_name, productcategories: [:productcategory_id]) 16 17puts p2[:productcategories][:productcategory_id] 18# => 2

期待通り 2 が得られました。
なぜ「取得できない」と思われたのでしょうか。

ところで,

rb

1def product_params 2 product_params = params.require(:product).permit(:id, :product_name, productcategories: [:productcategory_id]) 3end

product_params = は不要です。
このローカル変数のスコープはメソッド内なのでよそで使われる可能性はありません。代入する意味が無いのです。

投稿2018/03/28 17:45

scivola

総合スコア2108

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

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

ruby_0ct

2018/03/28 18:40 編集

素早すぎるご回答ありがとうございます。 う〜ん、不思議です。 params[:product][:productcategories][:productcategory_id]だと取得できるのですが、 @product = Product.new(product_params)をした後にputs(@book.inspect)で確認してみると、 productcategory_idがnilとなっています。 ストロングパラメータに原因があるとしか思えなかったのですが.. [上のコメント修正 03:40]paramsではなく、ストロングパラメータです。 product_params = に関してもありがとうございます。 scaffoldで自動で生成されたので、そのままにしていました。
scivola

2018/03/28 18:51

puts(@book.inspect) じゃなくて puts(@product.inspect) ですよね? ちなみにこれは p @product と書けます。(p メソッドは平たく言うと inspect したやつを表示します) いろいろ間違っています。 一つの Productcategory に複数の Product があり,一つの Product は一つの Productcategory に属すのですよね? であれば,とりあえず, Product モデルは belongs_to :productcategory でなければならないし, Productcateogry モデルは has_many :product でなければなりません。あべこべです。
scivola

2018/03/28 18:52

scaffold で product_params = が付くのはありそうにないですが。
ruby_0ct

2018/03/29 17:19

色々混乱しておりました。 @productで合ってます。 has_manyとbelongs_toを修正しました。そうすると、プルダウンメニューが表示されなくなったため、 <%= f.fields_for(@product) do |c| %>に変更し、コントローラのnewアクションには @book.build_bookcategoryを追加しました。 そうすると、paramsのネスト部分が、productcategoryではなくproductに変わりました。 Parameters: {"product"=>{"product"=>{"productcategory_id"=>"2"}} ストロングパラメータもproductに変更しましが、相変わらずnilとなっています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問