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

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

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

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

Devise

Deviseとは、Ruby-on-Railsの認証機能を追加するプラグインです。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

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

Q&A

2回答

808閲覧

Railsでcollection_check_boxesとaccepts_nested_attributes_forを使って中間テーブルに保存したい

shohike

総合スコア8

Ruby on Rails 5

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

Devise

Deviseとは、Ruby-on-Railsの認証機能を追加するプラグインです。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

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

0グッド

0クリップ

投稿2018/01/25 04:45

編集2022/01/12 10:55

前提・実現したいこと

rails5でウェブアプリを作成しています。
devise4を使用しログイン周りを作成しました。

ユーザーのアカウント作成時にアドレスなどのアカウント情報と共に
ユーザーが選択したカテゴリも同時に保存したいです。

試したこと

User と Category で多対多の関係を構築し、中間モデルとしてuser_categoryを作成しました。
アカウント登録時に選択したカテゴリのidを保存したいため,
accepts_nested_attributes_for :user_categories
とし関連づけました。

それぞれのモデルは以下

###user.rb

has_many :user_categories, dependent: :destroy,foreign_key:"category_id" has_many :categories, through: :user_categories accepts_nested_attributes_for :user_categories,allow_destroy: true

###category.rb

has_many :user_categories, dependent: :destroy,foreign_key:"user_id" has_many :users, through: :user_categories

###user_category.rb

belongs_to :user belongs_to :category

また登録時にチェックボックスにより複数保存したいため、
viewでcollection_check_boxesを使いました。

###new.html.erb

<%= form_for(resource, as: resource_name, url: registration_path(resource_name) ,html: {id: 'example-form'}) do |f| %> --------------省略------------------- <div class="form-group"> <%= f.label :category ,'カテゴリーの選択' %><br /> <%= collection_check_boxes(:user, :category_ids,Category.where(is_recommended: true).limit(6), :id, :name) do |b| %> <%= b.label {b.check_box + b.text } %> <% end %> </div> <% end %>

また保存の際にストロングパラメーターに設定しないといけないとの事でしたので、以下のように設定しました。
###application_controller

def configure_permitted_parameters devise_parameter_sanitizer.permit(:sign_up) do |user_params| user_params.permit({ roles: [] },:email,:password,:password_confirmation,:name, :birthday, :gender,user_categories_attributes: {:category_ids=> [] }) end end
def configure_permitted_parameters devise_parameter_sanitizer.permit(:sign_up,keys:[:name,:birthday,:gender,user_categories_attributes:[:id,:user_id,:category_ids => [] ]]) end

上記2パターンで試しましたがいづれも保存できないです。

submitボタンを押下すると以下のエラーがターミナルで表示され、DBには保存されませんでした。

発生している問題・エラーメッセージ

ターミナル

Unpermitted parameter: :category_ids

補足情報(FW/ツールのバージョンなど)

rails -v 5.1.4
ruby -v 2.4.1

devise -v 4.3

2日ほどかけて原因を探していますが、どこが原因なのか分からず、焦っております。。
お手数ですが、どなたか分かればヒントでもいいのでご教授いただけないでしょうか?
宜しくお願い致します。

------追記---------------

new.html.erb

<%= f.fields_for :category do |category| %> <%= collection_check_boxes :user_categories_attributes, :category_ids, Category.all, :id, :name %> <% end %>

上記により以下のパラメーターが取得できた

Parameters: {"utf8"=>"✓", "authenticity_token"=>"/wvgHWAqbewmsqXQ4UIrr8WDiafgQMAI07GL5dvdpV7KgvklrsyVajNAYWcwWVI6+TZ9BEh+oC4mkPNqyxumUg==", "user"=>{"name"=>"test18", "email"=>"test18@aaa.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "birthday(1i)"=>"1986", "birthday(2i)"=>"1", "birthday(3i)"=>"7", "gender"=>"1"}, "user_categories_attributes"=>{"category_ids"=>["", "2", "3", "6"]}, "commit"=>"次へ"}

が保存できないのでやはりストロングパラメーターの設定がおかしいのかもしれません

f configure_permitted_parameters devise_parameter_sanitizer.permit(:sign_up) do |user_params| user_params.permit({ roles: [] },:email,:password,:password_confirmation,:name, :birthday, :gender,user_categories_attributes: [category_ids:[] ]) end end

-------追記--------

<%= f.fields_for :category do |fc| %> <%= fc.collection_check_boxes :category_ids, Category.all, :id, :name %> <% end %>

にてポストしたところUnpermitted parameter: :categoryとなりましたので、

<%= f.label :user_categories_attributes ,'カテゴリーの選択' %><br /> <%= f.fields_for :user_categories_attributes do |fc| %> <%= fc.collection_check_boxes :category_ids, Category.all, :id, :name ,include_hidden: false%> <% end %>

へ変更し以下のパラメータで正しいように思われますが、

Parameters: {"utf8"=>"✓", "authenticity_token"=>"HrQJPZyDbz+j1yr0hxLI98PeiidIwAHx4rOey+U2QOCvDz90lZjhZgwGdczGx6uCtdzvt9px4GpD/LuoNxrI5w==", "user"=>{"name"=>"sasasa", "email"=>"sasasa@aaa.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "user_categories_attributes"=>{"category_ids"=>["3", "5", "6"]}, "birthday(1i)"=>"1984", "birthday(2i)"=>"1", "birthday(3i)"=>"1", "gender"=>"1"}, "commit"=>"次へ"}

#TypeError in Users::RegistrationsController#create
no implicit conversion of String into Integer
となりました。deviseのRegistrationsController を継承している以下のUsers::RegistrationsControllerのcreateアクションでの挙動がおかしいようです。。

イメージ説明

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

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

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

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

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

h_daido

2018/01/25 06:21 編集

rails console しているターミナルにformから渡されているパラメーターが出力されているはずです。postを投げた直後にログ出力されている内容を張ってみてもらえないですか?
shohike

2018/01/25 06:24 編集

こちらパラメーターになります。 Parameters: {"utf8"=>"✓","authenticity_token"=>"4eHGDUDs+InCJyMI1rIORLMqYJyGVFDQ5v+yXp4H7f6ELi/IVF+uk5viuHNlZevAbG3viHCQ0GUUE0Ew+MLS8A==", "user"=>{"name"=>"hughug", "email"=>"hughug@aaa.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "category_ids"=>["", "2", "3", "4"], "birthday(1i)"=>"1983", "birthday(2i)"=>"1", "birthday(3i)"=>"1", "gender"=>"1"}, "commit"=>"次へ"}
guest

回答2

0

パラメーターの構成がおかしいので、new.html.erbだと思いますね。
https://qiita.com/shingo-nakanishi/items/229ae20bc1ddf7192dfb
を参考にして、fileds_forタグを使ってみたらどうでしょう?


追記

AsIsのパラメーターでは以下のようになっているのですが、、、

{ "user"=>{ "name"=>"test22", "email"=>"test22@a.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "birthday(1i)"=>"1991", "birthday(2i)"=>"1", "birthday(3i)"=>"1", "gender"=>"1" }, "user_categories_attributes"=>{ "category_ids"=>["", "1", "3", "4"] } }

正しくは以下のようにならないと、accepts_nested_attributes_forが起動してくれません。
(※ user_categories_attributesの位置に注目してくださ)

{ "user"=>{ "name"=>"test22", "email"=>"test22@a.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "birthday(1i)"=>"1991", "birthday(2i)"=>"1", "birthday(3i)"=>"1", "gender"=>"1", "user_categories_attributes"=>[{ "category_ids"=>["", "1", "3", "4"] }] } }

ですので、おそらく対応箇所は以下です(実環境で試してないので、動かなかったらcollection_check_boxes helperのリファレンスを調べてみてください)

new.html.erb

html

1<%= f.fields_for :category do |fc| %> 2 <%= fc.collection_check_boxes :category_ids, Category.all, :id, :name %> 3<% end %>

投稿2018/01/25 06:30

編集2018/01/26 05:10
h_daido

総合スコア824

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

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

shohike

2018/01/25 06:32

ご回答いただきありがとうございます!リンク先確認させていただきます!!
shohike

2018/01/25 09:19

参考記事ありがとうございます!! fields_forで送信したらuser_categories_attributesでネストされたのですが、やはり保存できないままです。。パラメーターなどは上記に追記しましたので もし可能であればご回答頂けますと幸いです。
h_daido

2018/01/25 10:38 編集

パラメーターは正しそうですね。コンソールになにかメッセージが表示されてないですか?Unpermitted parameter xxx とか。可能なかぎりコンソールに表示されているログ情報を多くもらったほうが、原因特定しやすいかと思います。
shohike

2018/01/25 10:44

ご確認ありがとうございます。見たところ異常なところはなさそうなのですが ちなみに以下が吐き出されたログになります ``` Started POST "/" for 127.0.0.1 at 2018-01-25 19:42:15 +0900 Processing by Users::RegistrationsController#create as HTML Parameters: {"utf8"=>"✓", "authenticity_token"=>"JVnOpiU+j8ZkAv4cxtIFtUUErCddjVmn2gtqDUO7cKWuj/1LARC6bv3HCu7A7Guqgxi3NuzB/OZ+hAibccvX1A==", "user"=>{"name"=>"test22", "email"=>"test22@a.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "birthday(1i)"=>"1991", "birthday(2i)"=>"1", "birthday(3i)"=>"1", "gender"=>"1"}, "user_categories_attributes"=>{"category_ids"=>["", "1", "3", "4"]}, "commit"=>"次へ"} (0.4ms) BEGIN User Exists (0.9ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = $1 LIMIT $2 [["email", "test22@a.com"], ["LIMIT", 1]] SQL (1.2ms) INSERT INTO "users" ("email", "encrypted_password", "created_at", "updated_at", "name", "birthday", "gender") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["email", "test22@a.com"], ["encrypted_password", "$2a$11$G0.RvYabjfXw2YeqdHBgieEdoAXjOFN00DTYRG0pFT4YyObB5cgL."], ["created_at", "2018-01-25 10:42:15.878911"], ["updated_at", "2018-01-25 10:42:15.878911"], ["name", "test22"], ["birthday", "1991-01-01"], ["gender", "1"]] (15.7ms) COMMIT (0.3ms) BEGIN SQL (0.7ms) UPDATE "users" SET "sign_in_count" = $1, "current_sign_in_at" = $2, "last_sign_in_at" = $3, "current_sign_in_ip" = $4, "last_sign_in_ip" = $5, "updated_at" = $6 WHERE "users"."id" = $7 [["sign_in_count", 1], ["current_sign_in_at", "2018-01-25 10:42:15.899862"], ["last_sign_in_at", "2018-01-25 10:42:15.899862"], ["current_sign_in_ip", "127.0.0.1/32"], ["last_sign_in_ip", "127.0.0.1/32"], ["updated_at", "2018-01-25 10:42:15.901073"], ["id", 68]] (15.9ms) COMMIT Redirected to http://localhost:3000/ Completed 302 Found in 557ms (ActiveRecord: 35.2ms) ```
h_daido

2018/01/26 02:10

改めてみたところ、パラメーターがやはり少し異なるみたいですね。追記したので、確認してみてください。
shohike

2018/01/26 04:20

ご回答いただきましてありがとうございます。 パラメーターは正しく取れたようですがcreateアクション周りで引っかかっているようですので引き続き 調査してみます。
h_daido

2018/01/26 05:08

なるほど。一歩づつすすんでいるようですが、なかなか大変ですねw ちゃんとみれてないんですが、こちらと同じ事象かと。 https://stackoverflow.com/questions/35543875/nested-attributes-error-no-implicit-conversion-of-string-into-integer まだ、パラメーターがおかしいかもしれないですね。。。[]でarray化しないといけない? こちらに動作環境なくて、正しくつたえられてない情報もあってすいません。
guest

0

user.rb

has_many :user_categories, dependent: :destroy has_many :categories, through: :user_categories

category.rb

has_many :user_categories, dependent: :destroy has_many :users, through: :user_categories

user_category.rb

belongs_to :user belongs_to :category

db/migrate

class CreateUserCategory < ActiveRecord::Migration[5.2] def change create_table :user_category do |t| t.references :user, foreign_key: true, null: false t.references :category, foreign_key: true, null: false t.timestamps end end end

users_controller

def create category_params['category_ids'].each do |category_id| category = Category.find(category_id) user.categories << category end end private def category_params params.require(:テーブル).permit(category_ids: []) end

new.html.erb

<%= form_with model: @user, local: true do |f| %> <%= f.collection_check_boxes :category_ids, Category.all, :id, :name, include_hidden: false %> <%= f.submit "登録" %> <% end %>

多分こんな感じで行けます。

投稿2020/05/06 10:13

jack_kanzaki

総合スコア106

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問