问题
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 enddef 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