I am writing a Spree extension to allow certain items in the cart/order to be linked to each other.
A "setting" product can be associated with a "center stone" product. Eventually, there shall be constraints enforcing which things can reference each other, but that's not important yet.
Here's how I've changed the LineItem to include self references:
Spree::LineItem.class_eval do
has_one :center_stone, class_name: "LineItem", foreign_key: "setting_id"
belongs_to :setting, class_name: "LineItem"
end
...and the corresponding DB migration:
class AddSettingRefToLineItems < ActiveRecord::Migration
def change
add_reference :spree_line_items, :setting, index: true, foreign_key: true
end
end
What I need to accomplish next is to modify the "Add to Cart" form on the product page so that an item being added to the cart can get associated with an item that is already in the cart. How do I do this?
Use Case Example
Product A and Product B are both in my cart. I am looking at the page for Product C. I want to see the options:
Clicking any of these options creates a Spree::LineItem for Product C as usual. If click the first two option, I also want the LineItem for Product C's setting_id to reference the LineItem for Product A in my cart.
As was discovered, the main questions is: how to customize Spree's "add to card" function.
You need to customize views:
Deface::Override.new(:virtual_path => 'spree/products/_cart_form',
:name => 'centerproduct_cart_form',
:replace => "<what to replace>",
:erb => "<with what to replace>")
This should go to your app/overrides/centerproduct_cart_form.rb
file (you can change name of file, just make sure name
parameter in the code sample above will be changed as well to the same value).
You can figure out what to replace
and with what to replace
parts by looking at the source code of the view:
https://github.com/spree/spree/blob/master/frontend/app/views/spree/products/_cart_form.html.erb