I'm trying to create an order form that also serves as a list for all the available products. I have the models with the has_many through associations, and I managed to create collection_select fields to create the records on the join model which works fine, but I cannot figure out how to build a list showing each product and accepting additional attributes for the join records.
My models (somewhat simplified, I also have images and such):
class Supply < ActiveRecord::Base
attr_accessible :available, :name
has_many :order_lines
has_many :orders, through: :order_lines
accepts_nested_attributes_for :order_lines
end
class Order < ActiveRecord::Base
attr_accessible :month, :user_id, :order_lines_attributes
belongs_to :user
has_many :order_lines
has_many :supplies, through: :order_lines
accepts_nested_attributes_for :order_lines
end
class OrderLine < ActiveRecord::Base
attr_accessible :amount, :supply_id, :order_id
belongs_to :order
belongs_to :supply
validates_presence_of :amount
end
Order controller:
def new
@order = Order.new
@supplies = Supply.available
@supplies.count.times { @order.order_lines.build }
respond_to do |format|
format.html # new.html.erb
format.json { render json: @supply_order }
end
end
Order_line field from Order form:
<%= f.fields_for :order_lines do |order_line| %>
<%= order_line.label :amount %>
<%= order_line.number_field :amount %>
<%= order_line.label :supply_id %>
<%= order_line.collection_select(:supply_id, @supplies, :id, :name) %>
<% end %>
In place of this I would like to have a list with one order_line per supply (with name and other attributes) which gets saved if there's an amount defined. Any help appreciated!
Just add an order_item for each supply. Instead of this:
@supplies.count.times { @order.order_lines.build }
Do this:
@supplies.each { |supply| @order.order_lines.build(supply: supply) }
Then in your order form you don't need the collection_select for supply_id, just show the name:
<%= order_line.object.supply.name %>
Make sure you ignore nested attributes with an empty amount:
accepts_nested_attributes_for :order_lines, reject_if: proc { |attr| attr.amount.nil? || attr.amount.to_i == 0 }
You don't need the accepts_nested_attributes_for in the Supply model.