代码之家  ›  专栏  ›  技术社区  ›  christo16

Rails3-嵌套对象表单(重用地址模型)

  •  3
  • christo16  · 技术社区  · 14 年前

    我有一个商业模式和一个地址模式。为了使事情更复杂,我还有一个位置模型。一个企业可以有多个地址,但只能有一个邮寄地址。

    这是一个简单的目标图。


    -姓名

    位置
    -商业

    -地址

    我想对这两个业务和地点重复使用地址模型。我需要做些什么。如果有帮助的话,我用的是MySQL。

    首先我如何构造模型?我需要有很多:地点,:业务(地点/业务)?

    谢谢!

    2 回复  |  直到 14 年前
        1
  •  8
  •   Patrick Robertson    14 年前

    我将从一些基本的模型代码开始,然后转到控制器,然后是视图。

    首先是模型:

    #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>
    

    如果希望从与业务地址关联的位置集合中填充业务邮件地址,则可以在业务模型中添加一个方法,该方法执行以下操作:

    #app/models/business.rb#possible_mailing_addresses
    def possible_mailing_addresses
      Location.where(:business_id=>self.id).joins(:address)
    end
    
        2
  •  0
  •   Chowlett    14 年前

    关于模型,您可能需要这样的东西:

    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 是邮寄地址吗 每一项业务。

    红宝石专家 :我相信你会有生意的 has_one :mailing_address 使用 :through => :locations :source ,但我不明白 做。也许你能启发我们两个?