This question concerns three models:
class Sale < ActiveRecord::Base
has_many :sale_items
has_many :items, through :sale_items
end
class Item < ActiveRecord::Base
has_many :sale_items
has_many :sales, :through => :sale_items
end
class SaleItem < ActiveRecord::Base
belongs_to :sale
belongs_to :item
end
To explain, an item
acts as a base template for a sale_item
. The application has many Item
s, but these are not necessarily a part of every Sale
. So, sale_item.name
actually points to sale_item.item.name
, and sale_item
's price
method looks like this:
def price
super || item.price
end
A sale_item
either gets its price from its item
, or that price can be overridden for that specific sale_item
by editing its price
column in the database.
This is what I'm having difficulty with in my sales/_form.html.erb
view: I essentially need a table of all Item
objects that looks the table in this Tinkerbin: http://tinkerbin.com/46T7JAKs.
So, what that means is that if an unchecked checkbox gets checked and the form is submitted, a new SaleItem
needs to be created with an item_id
equal to that if the Item
from the list, and with appropriate price
and quantity
fields (quantity
is specific to SaleItem
and does not exist for Item
objects).
Additionally, if the Sale
that is being edited already includes a specific SaleItem
, that checkbox should already be checked when the form view is rendered (so unchecking a box for a row would delete the SaleItem
object associated with that Item
and this Sale
).
I'm not sure how this could be done—maybe I'm doing it wrong from the beginning. I toyed with the idea of doing away with the SaleItem
model altogether and just creating a items_sales
table with the fields sale_id
, item_id
, price
, and quantity
, but I'm not sure that is the best pattern.
The previous solution I posted ended up with some flaws and failing tests. I finally figured it out, but will post the real solution shortly.
What you want to have is a checkbox tag with an array which will hold on submission an array of all selected id's, so instead of the html checkbox use the checkbox helper:
<%= check_box_tag 'sale_item_ids[]', item.id -%>
On submission the params hash will hold the ids of the selected item's. What you need to do now is loop on each of these and do the appropriate creation of the relationship (sale_item). You must also loop on those that exist already for this sale and delete them if they are not in the array submited.
Upon creating the actual html page you can check if the id of the checkbox is already in the sale and check/uncheck it accordingly.
Hope this helps :)