2017-11-06 5 views
1

has_many :throughの関連付けからレコードを保存する際に問題が発生しました。私は何か重要なことを見逃しているに違いない。最初Rails 5.1.4 - has_many:throughの関係で複数選択からレコードを作成するにはどうすればよいですか?

まず物事:

  • Railsのバージョン:5.1.4
  • Rubyのバージョン:私はこれらの三つのモデルを持っ2.4.2

class Event < ApplicationRecord 
    has_many :events_timeslots 
    has_many :timeslots, through: :events_timeslots 
end 

class Timeslot < ApplicationRecord 
    has_many :events_timeslots 
    has_many :events, through: :events_timeslots 
end 

class EventsTimeslot < ApplicationRecord 
    belongs_to :event 
    belongs_to :timeslot 
end 

によると、これは、すべてのイベントには多くのタイムスロットがあり、すべてのタイムスロットには多くのイベントがあります。私は、マルチ私の見解で選択したい

<%= form_with(model: event, local: true) do |form| %> 
    ... 
    <% fields_for :events_timeslots do |events_timeslots| %> 
    <%= events_timeslots.label :timeslots %> 
    <%= events_timeslots.select(:timeslots, @timeslots.collect {|t| [t.name, t.id]}, {}, {multiple: true}) %> 
    <% end %> 
    ... 
<% end %> 

が、これは新しいイベントを作成しながら、複数のタイムスロットを選択するための適切なアプローチですか?この時点でタイムスロットは既に存在しますが、イベントが保存されると、events_timeslotsテーブルに関連するレコードも作成されます。

私はまた、強力なパラメータでtimeslots属性を許可:

params.require(:event).permit(:date, timeslots: []) 

はEventsTimeslotモデルに新しいイベントを作成するための「足場」のコントローラのアクションだけでなく、関連レコードを使用するために魔法のRails-方法があります?この質問に関連して、私はan answer on another questionを見つけましたが、それを動作させることができませんでした!

多分私は非常にばかげた小さなことを逃したが、とにかく助けてくれてありがとう。


編集

schema.rb中(めちゃくちゃ)events_timeslotsテーブル:

create_table "events_timeslots", force: :cascade do |t| 
    t.bigint "events_id" 
    t.bigint "timeslots_id" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
    t.index ["events_id"], name: "index_events_timeslots_on_events_id" 
    t.index ["timeslots_id"], name: "index_events_timeslots_on_timeslots_id" 
end 

答えて

3

と仮定すると、あなたの外部キーは標準です:event_idとおそらく、その後、10 ...

permit方法でtimeslot_idstimeslotsを交換してみてください:

params.require(:event).permit(:date, timeslot_ids: [])

その後、むしろ、ネストされた形で参加するテーブルの属性を設定するよりも、単にtimeslot_ids上を更新@event

<%= form_with(model: event, local: true) do |form| %> 

    <%= form.select(:timeslot_ids, Timeslot.all.collect {|t| [t.name, t.id]}, {}, {multiple: true}) %> 

<% end %> 
+1

"あなたの外部キーが標準であると仮定します" - そうではありませんでした!誤って 'events_id'と' timeslots_id'という名前を付けました。これで 'timeslot_ids'と調整された形式で完全に動作します。外部キー名を確認する重要なヒントをありがとう! :) – mabu

0

fields_forあなたはとネストされたレコードを作成しているときのためにあります。

あなたは、単に項目を関連付けるされている場合は必要ありません。その:

<%= form_with(model: event, local: true) do |form| %> 
    <%= f.collection_select(:timeslot_ids, Timeslot.all, :id, :name, multiple: true) %> 
<% end %> 

ActiveRecordのは、IDの配列を受け取りにhas_manyアソシエーションの_ids setterメソッドを作成します。これはform helpersと手を携えて動作します。 []許可に任意のスカラー値を使用して

params.require(:event).permit(:foo, :bar, timeslot_ids: []) 

:あなたが許可するキーワードとしてそれを渡す必要があり、配列のparamをホワイトリストに

関連する問題