Использование acceptpts_nested_attributes_for с ассоциацией own_to и использование поведения find_or_create_by_attr - PullRequest
2 голосов
/ 04 июня 2010

Я создаю приложение 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 и seen_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 Ответ

2 голосов
/ 14 июня 2010

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

http://gist.github.com/437939

...