Использовать композицию в Rails

Я не знаю, как лучше и правильнее что-то сделать, поэтому жду предложений.

Этап: я использую Rails 3 для создания веб-приложения. Изображение двух моделей: Canvas и Zone. Объект canvas задуман как квадрат, в котором будет четыре zone (север, юг, восток и запад). Каждый zone имеет следующие атрибуты: text:string и rgb_color:string. Я хочу отобразить HTML-форму, в которой пользователь должен захватить реестр Canvas, другими словами, в этой форме будет четыре группы полей зон.

Проблема: как я могу зафиксировать их все в одной HTML-форме?

Если бы у меня была только одна зона, я мог бы сделать что-то вроде этого:

<%= form_for(@zone) do |f| %>
  <div class="field">
    <%= f.label :text %><br />
    <%= f.text_field :text %>
  </div>
  <div class="field">
    <%= f.label :rgb_color %><br />
    <%= f.text_field :rgb_color %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

Но как мне это сделать с четырьмя зонами?


person Israel    schedule 09.10.2011    source источник


Ответы (1)


Вы можете сделать это с помощью accepts_nested_attributes_for и fields_for:

Модель:

class Canvas < ActiveRecord::Base
  has_many :zones
  accepts_nested_attributes_for :zones
end

Контроллер:

class CanvasesController < ApplicationController
  def new
    @canvas = Canvas.new
    4.times { @canvas.zones.build }
  end
end

Вид:

<%= form_for(@canvas) do |f| %>
  <%= f.fields_for :zones do |zone| %>
    <div class="field">
      <%= zone.label :text %><br />
      <%= zone.text_field :text %>
    </div>
    <div class="field">
      <%= zone.label :rgb_color %><br />
      <%= zone.text_field :rgb_color %>
    </div>
  <% end %>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

Для получения более подробной информации и объяснений взгляните на это:

person Mischa    schedule 09.10.2011
comment
Большое спасибо за ответ! Я проверю это. - person Israel; 09.10.2011
comment
Еще один вопрос... Есть ли способ сделать транзакцию, чтобы гарантировать сохранение всех моделей? Должны быть сохранены/обновлены Canvas и их четыре зоны, при выходе из строя одной из них необходимо откатить все. - person Israel; 09.10.2011
comment
@NeoRiddle, рад слышать, что это работает. Что касается проверки ваших вложенных атрибутов, не уверен. Вы можете использовать reject_if с accepts_nested_attributes_for и, возможно, этот вопрос актуален. Если вы не можете понять это, просто откройте новый вопрос. Удачи. - person Mischa; 09.10.2011