I followed thos steps http://railscasts.com/episodes/197-nested-model-form-part-2
I created a select box with suppliers so when I select a supplier will show all purchases that has a supplier selected updating the nested form.
Here my tables
suppliers
|id| |name|
1 AAAA
2 BBBB
shopping_documents
|id| |supplier_id|
1 1
2 2
shopping_products
|id| |shopping_document_id| |qty| |purchase_product_id|
1 1 1 1
2 1 1 2
3 2 1 3
purchase_products
|id| |name| |description| |cost| |supplier_id|
1 XP CD-ROM 1000 1
2 VISTA CD-ROM 2000 1
3 W7 CD-ROM 3000 2
Here is the controller /app/controller/purchase_product_controller.rb
class ShoppingDocumentController < ApplicationController
def new
@document = ShoppingDocument.new
@suppliers= Supplier.all
@purchases = PurchaseProduct.all
1.times do
shopping_product = @document.shopping_products.build
end
end
def create
@document = ShoppingDocument.new(params[:shopping_document])
if @document.save
flash[:notice] = "Successfully created document."
redirect_to :action=>"index"
else
render :action => 'new'
end
end
def update_nested_div
@purchases= PurchaseProduct.find(:all,:conditions=>['supplier_id =? ',params[:suppliers] ])
end
end
Here models:
class ShoppingDocument < ActiveRecord::Base
has_many :shopping_products
accepts_nested_attributes_for :shopping_products ,:allow_destroy => true
end
class ShoppingProduct < ActiveRecord::Base
belongs_to :shopping_document
belongs_to :purchase_product
end
class PurchaseProduct < ActiveRecord::Base
has_many :shopping_products
end
Here is the view: /app/view/purchase_product/new.html.erb
<% form_for @document, :url => {:controller=>"shopping_document",:action=>'create'} do |f| %>
Name: <%= select_tag 'suppliers',"<option value=\"\">Select</option>"+options_for_select(@suppliers.collect {|t| [t.name,t.id]} ),:onchange=>remote_function(:url=>{:controller=>"shopping_document",:action=>"update_nested_div"},:with=>"'suppliers=' + $('suppliers').value"),:name=>"shopping_document[supplier_id]" %>
<% f.fields_for :shopping_products do |builder| %>
<%= render "shopping_product_fields", :f => builder %>
<% end %>
<p><%= link_to_add_fields "Add Product", f, :shopping_products %></p>
<p><%= f.submit "Submit" %></p>
<% end %>
Here is the partial view: /app/view/shopping_document/_shopping_product_fields.html.erb
<div class="nested_form">
<%= f.select :purchase_product_id,@purchases.map { |c| [c.cost, c.id] },{},:id=>"helping" %> %>
Quantity: <%= f.text_field :qty %> <%= link_to_remove_fields "remove", f %>
</div>
Here is the view rjs : /app/view/shopping_document/_update_nested_div.rjs
page.replace_html 'helping', options_for_select(@purchases.map{|c| [c.cost, c.id]})
Is working perfect but is just working with the first nested select box , If I add click on "Add Product" the second or next or more won't be according the supplier selected and will show all suppliers.
Please somebody can help me with this issue?
Is just working only on the first nested select box if I add another won't show values according the supplier selected just show all .
EDIT 8/11 9pm
You can set a class instead of an id on the select tag you want to change the options of based on the supplier selection.
<%= f.select :purchase_product_id,@purchases.map { |c| [c.cost, c.id] }, {}, :class => "helping" %>
And then change your /app/view/shopping_document/_update_nested_div.rjs with the following:
page.select('.helping').each do |select_tag|
page.replace_html select_tag, options_for_select(@purchases.map{|c| [c.cost, c.id]})
end
The problem you had was that replace_html works on the first element it finds with the id "helping". With a class and page.select, we get a collection of select tags from which we have to the options by iterating on them.
The pattern I use is described in the Rails 2.3.8 api documentation. Check it out for the other methods available.