Rails 3 - вложенные объектные формы (повторное использование адресной модели) - PullRequest
3 голосов
/ 12 ноября 2010

У меня проблемы с нахождением головы вокруг этой проблемы.

У меня есть бизнес-модель и модель адреса.Чтобы сделать вещи более сложными, у меня также есть модель местоположения.Бизнес может иметь несколько местоположений, но только один почтовый адрес.

Вот простая диаграмма объектов.

Бизнес
-Имя
-MailingAddress

Местоположение
-Бизнес
-Имя
-Адрес

Я хочу повторно использовать модель адреса для обоих предприятийИ места.Что мне нужно для этого сделать.Если это помогает, я использую MySQL.

Во-первых, как мне структурировать модели?Нужно ли иметь has_many: location,: business (для Location / Business)?Тогда как мне вложить формы для создания адресов в новые формы Business / Location.

Спасибо!

Ответы [ 2 ]

8 голосов
/ 12 ноября 2010

Я начну с некоторого базового кода модели, затем перейду к контроллеру, затем просмотрю.

Сначала модели:

#app/models/business.rb
class Business < ActiveRecord::Base
  has_one :mailing_address, :class_name => "Address", :dependent => :destroy
  accepts_nested_attributes_for :mailing_address

  has_many :locations
  accepts_nested_attributes_for :locations
end

#app/models/location.rb
class Location < ActiveRecord::Base
  has_one :address, :dependent => :destroy
  accepts_nested_attributes_for :address

  belongs_to :business
end

#app/models/address.rb
class Address < ActiveRecord::Base
  belongs_to :business
  belongs_to :location
end

Теперь новое действие контроллера:

#app/controllers/businesses_controller.rb#new
def new
  @business = Business.new

  mailing_address = @business.build_mailing_address
  3.times do
    location = @business.locations.build
    address = location.build_address
  end
  respond_to do |format|
    format.html # new.html.erb
    format.xml  { render :xml => @business }
  end
end

Наконец, представления:

#app/views/businesses/_form.html.erb
<%= form_for(@business) do |f| %>
  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </div>
  <%= f.fields_for :mailing_address do |builder| %>
    <h3>Mailing Address</h3>
    <%= render "address_fields", :f => builder %>
  <% end %>
  <%= f.fields_for :locations do |builder| %>
    <h3>Location</h3>
    <%= render "locations_fields", :f => builder %>
    <%= builder.fields_for :address do |mini_builder| %>
      <h3>Location Address</h3>
      <%= render "address_fields", :f => mini_builder %>
    <% end%>
  <% end %>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

частичный адрес:

#app/views/businesses/_address_fields.html.erb
<p>
  <%= f.label "Street Address"%>
  <%= f.text_field :street %>
  <%= f.label "City"%>
  <%= f.text_field :city %>
  <%= f.label "State"%>
  <%= f.text_field :state %>
  <%= f.label "Zip"%>
  <%= f.text_field :zip %>  
</p>

частичный адрес:

#app/views/businesses/_location_fields.html.erb
<p>
  <%= f.label "Location Name"%>
  <%= f.text_field :name%>
</p>

В этом есть несколько хитрых компонентовВсе это.Следует помнить, что создание дочернего объекта has_one и has_many - это другой метод в контроллере.Кроме того, вам нужно правильно определить класс для отношения почтового адреса.

Если вы хотите заполнить почтовый адрес организации из набора местоположений, связанных с адресами организации, вы можете добавить метод в Business.модель, которая сделала что-то вроде этого:

#app/models/business.rb#possible_mailing_addresses
def possible_mailing_addresses
  Location.where(:business_id=>self.id).joins(:address)
end
0 голосов
/ 12 ноября 2010

Что касается моделей, вы, вероятно, захотите что-то вроде этого:

class Business < ActiveRecord::Base
  has_many :locations
  has_many :addresses, :through => :locations do
    def mailing
      find_by_is_mailing_address(true)
    end
  end
end

class Location < ActiveRecord::Base
  has_one :address
  belongs_to :business
end

class Address < ActiveRecord::Base
  belongs_to :location
  belongs_to :business, :through => :location      
end

... это даст вам my_business.addresses.mailing.

Затем вам понадобится логический столбец в вашем addresses таблица с именем is_mailing_address, которую вы устанавливаете true только для адреса, который является почтовым адресом для ее бизнеса.Вы также должны проверить в модели Address, что только один адрес is_mailing_address для каждого Бизнеса.

Боюсь, я не очень опытен во вложенных формах;надеюсь, кто-то еще может помочь вам.

Эксперты по Ruby : Я уверен, что вы могли бы использовать Business has_one :mailing_address, используя :through => :locations и :source, но я не понимаю, что:source делает.Возможно, вы могли бы просветить нас обоих?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...