[英]Rails 5.1.4 - How do I create records from multi-select with a has_many :through relationship?
I got some problems with saving records from a has_many :through
association. 我从
has_many :through
关联保存记录时遇到了一些问题。 I must have missed something important. 我一定错过了重要的事情。
First things first: 第一件事:
I got these three models: 我得到了以下三种模型:
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
According to this, every event has many timeslots and every timeslot has many events. 据此,每个事件具有许多时隙,并且每个时隙具有许多事件。
I want a multi select in my view: 我想在视图中进行多重选择:
<%= 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 %>
Is this the right approach to select multiple timeslots while creating a new event? 这是在创建新事件时选择多个时隙的正确方法吗? The timeslots already exist at this time but when the event gets saved, it should also create the associated records in the
events_timeslots
table. 此时该时隙已经存在,但是当保存事件时,它还应该在
events_timeslots
表中创建关联的记录。
I also permit the timeslots
attribute in strong parameters: 我还允许在强参数中使用
timeslots
属性:
params.require(:event).permit(:date, timeslots: [])
Is there a magic Rails-Way to use the "scaffolded" controller actions to create the new event as well as the associated records in EventsTimeslot model? 是否有一个神奇的Rails-Way使用“脚手架”控制器操作来创建新事件以及EventsTimeslot模型中的关联记录? Related to this question I found an answer on another question , however I wasn't able to get it to work!
与此问题相关,我找到了另一个问题的答案 ,但是我无法使其正常工作!
Maybe I missed a very stupid little thing, but anyways thanks for the help. 也许我错过了一个非常愚蠢的小事情,但是无论如何都感谢您的帮助。
Edit 编辑
The (messed up) events_timeslots
table in schema.rb
: schema.rb
的( events_timeslots
) 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
Assuming your foreign keys are the standard: event_id
and timeslot_id
... 假设您的外键是标准的:
event_id
和timeslot_id
...
Then perhaps try swapping timeslots
with timeslot_ids
in the permit
method: 然后也许尝试在
permit
方法中将timeslots
与timeslot_ids
交换:
params.require(:event).permit(:date, timeslot_ids: [])
Then, rather than setting the attributes of the join table in a nested form, just update the timeslot_ids
on the @event
: 然后,而不是嵌套形式设置连接表的属性,只需更新
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 %>
fields_for
is for when you are creating nested records with accepts_nested_attributes
. fields_for
用于在创建带有accepts_nested_attributes
嵌套记录时。
Its not needed when you are simply associating items: 当您简单地关联项目时,不需要它:
<%= form_with(model: event, local: true) do |form| %>
<%= f.collection_select(:timeslot_ids, Timeslot.all, :id, :name, multiple: true) %>
<% end %>
ActiveRecord creates a _ids
setter method for has_many associations that takes an array of ids. ActiveRecord为has_many关联创建一个
_ids
setter方法,该方法采用ID数组。 This works hand in hand with the form helpers . 这与表单帮助器协同工作。
To whitelist an array param you need to pass it as a keyword to permit: 要将数组参数列入白名单,您需要将其作为关键字传递以允许:
params.require(:event).permit(:foo, :bar, timeslot_ids: [])
Using []
permits any scalar value. 使用
[]
允许任何标量值。
我认为您正在寻找“自动保存”,请在此处查看http://api.rubyonrails.org/classes/ActiveRecord/AutosaveAssociation.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.