RoR - 在多对多连接表上创建记录

时间:2014-08-31 19:05:25

标签: ruby-on-rails many-to-many jointable

我有以下型号:

Client.rb
  has_many :establishments
  accepts_nested_attributes_for :establishments

  has_many :addressess, through: :establishments
  accepts_nested_attributes_for :addresses


Establishment.rb
  belongs_to :address
  belongs_to :client


Address.rb
  has_many :establishments 

show的{​​{1}}视图中,我创建了一个Client,以便为客户创建新的地址记录和新的机构。

在我<%= link_to "New Establishment", new_client_address_path(@client)%>上:     

     def new
        @client = Client.find(params[:client_id])
        @address = @client.addresses.build
      end

AddressController

这将创建新地址,但不会创建新的建立。这可以自动创建链接 def create @address = Address.new(address_params) respond_to do |format| if @address.save format.html { redirect_to @address, notice: 'Estabelecimento criado com sucesso.' } format.json { render action: 'show', status: :created, location: @address } else format.html { render action: 'new' } format.json { render json: @address.errors, status: :unprocessable_entity } end end end Client的新建立吗?在你提问之前,我真的需要这个Address模型。

2 个答案:

答案 0 :(得分:0)

下面:

在你的模特中:

Client.rb
  has_many :establishments
  accepts_nested_attributes_for :establishments

  has_many :addresses, through: :establishments
  accepts_nested_attributes_for :addresses


Establishment.rb
  belongs_to :address
  belongs_to :client


Address.rb
  has_many :establishments
  has_many :clients, through: :establishments

在您的控制器中:

class AddressController < ApplicationController

  def new
    @client = Client.find(params[:client_id])
    @client.establishments.build.build_address
    # if you have a column in establishment, for example: name
    # you can do something like this to set establishment's name:
    # @client.establishments.build(name: 'First connection').build_address
  end

  # create method doesn't need to be changed!!

end
在您看来

<%= form_for(@client) do |form| %>
  <%= form.input :name %>

  <%= form.fields_for(:establishments) do |establishment_form| %>
    <% establishment = establishment_form.object.name.titleize %>
    <%= establishment_form.input :name, as: :hidden %>
    <%= establishment_form.fields_for(:address) do |address_form| %>
      <%= address_form.input :address1, label: "#{establishment} address1" %>
      <%= address_form.input :address2, label: "#{establishment} address2" %>
    <% end %>
  <% end %>

  <%= form.submit "Submit" %>
<% end %>

并且你已经全部准备好了!!

答案 1 :(得分:0)

首先要做的事情 - 您将无法使用accepts_nested_attributes_for :addresses调用 - 您只能通过直接连接的模型传递关联数据

我将解释如何传递您想要的数据,但首先让我解释一下如何正确执行此操作:

-

收集数据

如果您想通过联接表关联两个现有对象,您将能够使用collection methods in ActiveRecord中的一些,即other_ids

#app/views/clients/new.html.erb
<%= form_for @client do |f| %>
   <%= f.collection_select :establishment_ids, Establishment.all, :id, :name %>
   <%= f.submit %>
<% end %>

这将填充[other]_ids模型中的Client方法,该方法基本上会填充您拥有的has_many :through联接模型。

这仅适用于您希望与新创建的Establishment关联的Client条记录。

-

嵌套属性

如果您要创建新的Establishment记录,则必须将数据发送到Address模型,然后发送到Establishment模型:

#app/models/client.rb
class Client < ActiveRecord::Base
   has_many :establishments
   has_many :addresses, through: :establishments
end

#app/models/establishment.rb
class Establishment < ActiveRecord::Base
   belongs_to :client
   belongs_to :address
   accepts_nested_attributes_for :address
end

#app/models/address.rb
class Address < ActiveRecord::Base
   has_many :establishments
   has_many :clients, through: :establishments
end

这将允许您致电:

#app/controllers/clients_controller.rb
class ClientsController < ApplicationController
   def new
     @client = Client.new
     @client.establishments.build.build_address
   end

   def create
      @client = Client.new client_params
      @client.save
   end

   private 

   def client_params
      params.require(:client).permit(establishments_attributes: [address_attributes:[]])
   end
end

这将允许您使用以下表格:

#app/views/cients/new.html.erb
<%= form_for @client do |f| %>
   <%= f.fields_for :establishments do |e| %>
      <%= e.fields_for :address do |a| %>
         ...
      <% end %>
   <% end %>
   <%= f.submit %>
<% end %>