Использование acceptpts_nested_attributes_for с ассоциацией own_to и использование поведения find_or_create_by_attr
Я создаю приложение 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 и visible_property являются односторонними, возвращение has_many отсутствует.)
Контроллер - это не что-то особенное, просто стандартная семерка REST, и я думаю, что было бы возможно сделать это правильно, сохранив большую часть логики в модели.
Вместо того, чтобы пользователь заполнял несколько различных форм и затем ссылался на эти объекты отдельно, я попытался использовать 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
, но это не похоже на правильный способ делать вещи.
1 ответ
В итоге я использовал следующее решение, и оно, похоже, работает. Я создал суть для решения с соответствующей спецификацией, чтобы определить поведение, которое я искал.