问题
I have the following models:
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
On the show view of the Client I created a <%= link_to "New Establishment", new_client_address_path(@client)%> in order to create a new Address record and a new Establishment to the client.
On the AddressController I have:
def new
@client = Client.find(params[:client_id])
@address = @client.addresses.build
end
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
this will create the new Address but does not create the new Establishment. Can this automatically create the new Establishment that links the Client and the Address? Before you ask, I really need to have this Establishment model.
回答1:
First things first - you won't be able to use the accepts_nested_attributes_for :addresses call - you can only pass associative data through immediately connected models
I'll explain how to pass the data you want, but first let me explain how to do this correctly:
--
Collection Data
If you want to associate two existing objects through a join table, you'll be able to use some of the collection methods in ActiveRecord, namely 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 %>
This will populate the [other]_ids method in your Client model, which will essentially populate the has_many :through join model you have.
This will only work if you have Establishment records you already wish to associate with your newly created Client.
--
Nested Attributes
If you want to create a new Establishment record, you'll have to send the data to the Address model, and then to the Establishment model:
#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
This will allow you to call:
#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
This will allow you to use the following form:
#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 %>
回答2:
Here:
In you models:
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
in your controller:
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
in your view:
<%= 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 %>
and you're all set!!
来源:https://stackoverflow.com/questions/25595309/ror-create-record-on-many-to-many-join-table