将accepts_nested_attributes_for与belongs_to关联一起使用,并使用find_or_create_by_attr行为
-
24-10-2019 - |
题
我正在构建一个 Rails 应用程序,它允许用户创建一个引用多个其他模型的对象,如果它们不存在则创建它们,并且只关联到已经存在的模型:
# app/models/upload.rb
class Upload < AR:B
belongs_to :user
belongs_to :observed_property
belongs_to :sensor
accepts_nested_attributes_for :observed_property, :sensor
validates_presence_of :observed_property, :sensor
end
(与sensor和observed_property的关联只是单向的,没有has_many返回。)
控制器没什么特别的,只是一个标准的 RESTful 7,我认为可以在保留模型中的大部分逻辑的同时正确地做到这一点。
我没有让用户填写多个不同的表单,然后分别引用这些对象,而是尝试使用 accepts_nested_attributes_for
将它们嵌入到 Upload
形式使用 fields_for
:
# app/views/uploads/new.html.erb
<% form_for @upload, :url => user_uploads_path(@user) do |f| %>
<%= f.error_messages %>
<% f.fields_for :observed_property do |builder| %>
<fieldset>
<legend>Observed Property</legend>
<p><%= builder.label :_id, "Observed Property ID" %><br />
<%= builder.text_field :_id %></p>
<p><%= builder.label :description %><br />
<%= builder.text_area :description, :rows => 5 %></p>
</fieldset>
<% end %>
<% f.fields_for :sensor do |builder| %>
<fieldset>
<legend>Sensor</legend>
<p><%= builder.label :_id, "Sensor ID" %><br />
<%= builder.text_field :_id %></p>
<p><%= builder.label :description %><br />
<%= builder.text_area :description, :rows => 5 %></p>
</fieldset>
<% end %>
<%= f.submit "Submit", :class => "button" %>
<% end %>
然而,这不起作用,因为没有显示任何表格 fields_for
. 。我尝试应用中提到的内容 这个答案, ,但该模型将无法保存,因为缺少关联。
我尝试过一些黑客的事情,例如覆盖 sensor=
和 observed_property=
方法并缓存哈希值 before_save
, ,但这确实不是正确的做事方式。
解决方案
我最终使用了以下解决方案,它似乎确实有效。我创建了一个要点来保存具有匹配规范的解决方案,以定义我正在寻求的行为。
不隶属于 StackOverflow