I am trying to deal in form with 2 level nested resource. My parrent resource is supplier. I've done adding (building) new descedants (address) in new ad edit form. I've also done adding (building) descedant of descedant (contacts) in new form but I have problem with adding descedant of descedant (contacts) in edit form. In edit form I want to add submit button [Add contact] after each contact and when user click on this button go to update method and build new contact instance in proper address -I need send with [Add contact] submit param with address ID. I have no idea how to do it. I've try hidden field but it send last hidden fiel value from loop. It is any chance to send diffrent param with submit button?
I have 2 level nested resource. Supplier has descedant -> address Address has descedant -> contact
Models: Supplier:
has_many :supplier_addresses
has_many :addresses, :through => :supplier_addresses
accepts_nested_attributes_for :addresses,
:allow_destroy => true,
:reject_if => :all_blank
Address:
has_many :address_contacts
has_many :contacts, :through => :address_contacts
accepts_nested_attributes_for :contacts,
:allow_destroy => true,
:reject_if => :all_blank
Contact:
has_many :address_contacts
has_many :addresses, :through => :address_contacts
Suppliers_Controller:
class SuppliersController < ApplicationController
before_action :set_supplier, only: [:show, :edit, :update, :destroy]
def index
if params[:search]
@suppliers = Supplier.paginate(page: params[:page], :per_page => 15).by_letter(params[:search])
else
@suppliers = Supplier.paginate(page: params[:page], :per_page => 15).order(:name)
end
end
# GET /currencies/new
def new
@supplier = Supplier.new
ad=@supplier.addresses.build
ad.contacts.build
end
def show
end
def edit
ad=@supplier.addresses.build
ad.contacts.build
end
# POST /currencies
# POST /currencies.json
def create
@supplier = Supplier.new(supplier_params)
if add_address?
@supplier.addresses.build
respond_to do |format|
format.html { render :new }
format.json { render json: @supplier.errors, status: :unprocessable_entity }
end
elsif add_contact?
@supplier.addresses[params[:add_id].to_i].contacts.build
respond_to do |format|
format.html { render :new }
format.json { render json: @supplier.errors, status: :unprocessable_entity }
end
else
respond_to do |format|
if @supplier.save
flash[:info] = 'Supplier was successfully created.'
format.html { redirect_to @supplier }
format.json { render :show, status: :created, location: @supplier }
else
format.html { render :new }
format.json { render json: @supplier.errors, status: :unprocessable_entity }
end
end
end
end
# PATCH/PUT /currencies/1
# PATCH/PUT /currencies/1.json
def update
if add_address?
@supplier.addresses.build
respond_to do |format|
format.html { render :edit }
format.json { render json: @supplier.errors, status: :unprocessable_entity }
end
elsif add_contact?
@supplier.addresses[params[:add_id].to_i].contacts.build
respond_to do |format|
format.html { render :edit }
format.json { render json: @supplier.errors, status: :unprocessable_entity }
end
else
respond_to do |format|
if @supplier.update(supplier_params)
flash[:info] = 'Supplier was successfully updated.'
format.html { redirect_to supplier_url }
format.json { render :show, status: :ok, location: @supplier }
else
format.html { render :edit }
format.json { render json: @supplier.errors, status: :unprocessable_entity }
end
end
end
end
# DELETE /currencies/1
# DELETE /currencies/1.json
def destroy
@supplier.destroy
respond_to do |format|
flash[:info] = 'Supplier was successfully deleted.'
format.html { redirect_to suppliers_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_supplier
@supplier = Supplier.find(params[:id])
end
#for new add
def add_address?
params[:commit] == "Add address"
end
#for new add
def add_contact?
params[:commit] == "Add contact"
end
# Never trust parameters from the scary internet, only allow the white list through.
def supplier_params
params.require(:supplier).permit(:name, :notes, :min_order, :pay_terms,
addresses_attributes: [:id, :name, :street1, :street2, :county, :city, :country, :post_code, :_destroy,
contacts_attributes:[:id, :name, :job_title, :tel_no, :fax_no, :mobile_no, :email, :invoice_email, :contact_notes, :_destroy]])
end
end
Form:
<%= form_for(@supplier) do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.fields_for :addresses do |address| %>
<%= address.label :street %>
<%= address.text_field :street %>
<%= address.fields_for :contacts do |contact| %>
<%= contact.label :job_title %>
<%= contact.text_field :job_title %>
<%end%>
<%=hidden_field_tag params[:add_id], address.index%>
<div class="row">
<div class="actions text-center">
<%= f.submit "Add contact",:class => 'btn btn-sm btn-warning custom2' %>
</div>
</div>
<%end%>
<div class="row">
<div class="actions text-center">
<%= f.submit "Add address",:class => 'btn btn-sm btn-warning custom2' %>
<%= f.submit :class => 'btn btn-sm btn-success custom2' %>
</div>
</div>
<%end%>