Rails 5.1.4 - 如何从具有 has_many :through 关系的 multi-select 创建记录?
Rails 5.1.4 - How do I create records from multi-select with a has_many :through relationship?
我在保存来自 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
据此,每个事件有多个时间段,每个时间段有多个事件。
我想要一个多 select 在我看来:
<%= 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 %>
在创建新事件时,这是 select 多个时间段的正确方法吗?此时时间段已经存在,但是当事件被保存时,它还应该在 events_timeslots
table.
中创建关联记录
我还允许强参数中的 timeslots
属性:
params.require(:event).permit(:date, timeslots: [])
有没有神奇的方法Rails-使用"scaffolded" 控制器操作来创建新事件以及EventsTimeslot 模型中的关联记录?与这个问题相关,我发现 an answer on another question,但是我无法让它工作!
也许我错过了一件非常愚蠢的小事,但无论如何还是感谢您的帮助。
编辑
schema.rb
中的(搞砸了)events_timeslots
table:
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
我认为您正在寻找“自动保存”,请在此处查看 http://api.rubyonrails.org/classes/ActiveRecord/AutosaveAssociation.html
假设您的外键是标准的:event_id
和 timeslot_id
...
然后也许尝试在 permit
方法中将 timeslots
与 timeslot_ids
交换:
params.require(:event).permit(:date, timeslot_ids: [])
然后,不要以嵌套形式设置联接 table 的属性,只需更新 @event
上的 timeslot_ids
:
<%= form_with(model: event, local: true) do |form| %>
<%= form.select(:timeslot_ids, Timeslot.all.collect {|t| [t.name, t.id]}, {}, {multiple: true}) %>
<% end %>
fields_for
适用于使用 accepts_nested_attributes
.
创建嵌套记录的情况
当您只是简单地关联项目时不需要它:
<%= form_with(model: event, local: true) do |form| %>
<%= f.collection_select(:timeslot_ids, Timeslot.all, :id, :name, multiple: true) %>
<% end %>
ActiveRecord 为 has_many 关联创建了一个 _ids
setter 方法,它接受一个 id 数组。这与 form helpers.
一起工作
要将数组参数列入白名单,您需要将其作为关键字传递以允许:
params.require(:event).permit(:foo, :bar, timeslot_ids: [])
使用 []
允许任何标量值。
我在保存来自 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
据此,每个事件有多个时间段,每个时间段有多个事件。
我想要一个多 select 在我看来:
<%= 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 %>
在创建新事件时,这是 select 多个时间段的正确方法吗?此时时间段已经存在,但是当事件被保存时,它还应该在 events_timeslots
table.
我还允许强参数中的 timeslots
属性:
params.require(:event).permit(:date, timeslots: [])
有没有神奇的方法Rails-使用"scaffolded" 控制器操作来创建新事件以及EventsTimeslot 模型中的关联记录?与这个问题相关,我发现 an answer on another question,但是我无法让它工作!
也许我错过了一件非常愚蠢的小事,但无论如何还是感谢您的帮助。
编辑
schema.rb
中的(搞砸了)events_timeslots
table:
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
我认为您正在寻找“自动保存”,请在此处查看 http://api.rubyonrails.org/classes/ActiveRecord/AutosaveAssociation.html
假设您的外键是标准的:event_id
和 timeslot_id
...
然后也许尝试在 permit
方法中将 timeslots
与 timeslot_ids
交换:
params.require(:event).permit(:date, timeslot_ids: [])
然后,不要以嵌套形式设置联接 table 的属性,只需更新 @event
上的 timeslot_ids
:
<%= form_with(model: event, local: true) do |form| %>
<%= form.select(:timeslot_ids, Timeslot.all.collect {|t| [t.name, t.id]}, {}, {multiple: true}) %>
<% end %>
fields_for
适用于使用 accepts_nested_attributes
.
当您只是简单地关联项目时不需要它:
<%= form_with(model: event, local: true) do |form| %>
<%= f.collection_select(:timeslot_ids, Timeslot.all, :id, :name, multiple: true) %>
<% end %>
ActiveRecord 为 has_many 关联创建了一个 _ids
setter 方法,它接受一个 id 数组。这与 form helpers.
要将数组参数列入白名单,您需要将其作为关键字传递以允许:
params.require(:event).permit(:foo, :bar, timeslot_ids: [])
使用 []
允许任何标量值。