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

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

ただいまの
回答率

90.76%

  • Ruby

    7035questions

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

  • Ruby on Rails

    6750questions

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

  • Ruby on Rails 5

    1299questions

  • Devise

    235questions

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

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

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 328

shohike

score 2

 前提・実現したいこと

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アクションでの挙動がおかしいようです。。

イメージ説明

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • h_daido

    2018/01/25 15:20 編集

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

    キャンセル

  • shohike

    2018/01/25 15:23 編集

    こちらパラメーターになります。 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"=>"次へ"}

    キャンセル

回答 1

+1

パラメーターの構成がおかしいので、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

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/25 15:32

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

    キャンセル

  • 2018/01/25 15:39

    https://qiita.com/hmuronaka/items/818c421dc632e3efb7a6#create-1 がわかりやすいんですが、正しくは user_categories_attributesというパラメーターにネストされる形になるはずです!

    キャンセル

  • 2018/01/25 18:19

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

    もし可能であればご回答頂けますと幸いです。

    キャンセル

  • 2018/01/25 19:26 編集

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

    キャンセル

  • 2018/01/25 19: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)
    ```

    キャンセル

  • 2018/01/26 11:10

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

    キャンセル

  • 2018/01/26 13:20

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

    キャンセル

  • 2018/01/26 14:08

    なるほど。一歩づつすすんでいるようですが、なかなか大変ですねw
    ちゃんとみれてないんですが、こちらと同じ事象かと。
    https://stackoverflow.com/questions/35543875/nested-attributes-error-no-implicit-conversion-of-string-into-integer

    まだ、パラメーターがおかしいかもしれないですね。。。[]でarray化しないといけない?
    こちらに動作環境なくて、正しくつたえられてない情報もあってすいません。

    キャンセル

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

  • ただいまの回答率 90.76%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Ruby

    7035questions

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

  • Ruby on Rails

    6750questions

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

  • Ruby on Rails 5

    1299questions

  • Devise

    235questions

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