Использование 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 ответ

Решение

В итоге я использовал следующее решение, и оно, похоже, работает. Я создал суть для решения с соответствующей спецификацией, чтобы определить поведение, которое я искал.

http://gist.github.com/437939

Другие вопросы по тегам