Tutorial :Rails Model Associations for Item-Item Relationship?



Question:

Looking for some guidance on the best way to implement this scenario:

I have an items table (of products) and want to support the ability to cross-sell / up-sell / complement items. So there is an item-to-item(s) relationship here. In this join table I need to include additional attributes beyond the keys such as the sales_relation between the items (e.g., cross, up, complement, substitute, etc).

How do I go about setting up the Model associations?


Solution:1

By the sounds of it, this join table represents a whole new model. I'm not sure exactly what your requirements are, but I'll play out one potential solution. For now, let's call the join model a SalesRelationship.

I'm going to call the item/product objects "products", since to me it's a little less generic.

The migration for this would look something like:

class CreateSalesRelationship < ActiveRecord::Migration    def self.up      create_table :sales_relationship |t|        t.string :product_id        t.string :other_product_id        t.string :type        t.timestamps      end    end      def self.down      drop_table :sales_relationship    end  end  

You can include any other attributes necessary in that migration as well. Next, create a SalesRelationship model:

class SalesRelationship < ActiveRecord::Base    belongs_to :product    belongs_to :other_product, :class_name => "Product  end  

Then, create subclasses for the different types of relationship:

class CrossSell < SalesRelationship  end    class UpSell < SalesRelationship  end    class Complement < SalesRelationship  end    class Substitute < SalesRelationship  end  

Then set up the relationships on the Product model:

class Product < ActiveRecord::Base    has_many :sales_relationships, :dependent => :destroy    has_many :cross_sells    has_many :up_sells    has_many :complements    has_many :substitutes      has_many :cross_sale_products, :through => :cross_sells, :source => :other_product    has_many :up_sale_products, :through => :up_sells, :source => :other_product    has_many :complementary_products, :through => :complements, :source => :other_product    has_many :substitute_products, :through => :substitutes, :source => :other_product  end  

Now you should be able to create and add related products all you want.

@product1.substitute_products << @product2  new_product = @product2.complementary_products.build  

For extra credit, you could write a simple validation on the SalesRelationship model that ensures a product is never related to itself. That may or may not be necessary, depending on your requirements.


Solution:2

Something like this:

has_many :other_item, :class_name => "Item", :through => :item_to_item  

The table item_to_item would go like this

| item_id | other_item_id | complement | substitute | etc...  

You'll have to write a custom attribute accessor which makes sure that item_id is always < other_item_id to avoid issues with the duplicates.

Feel free to ask more if you don't quite understand what I mean here.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »