0

I am building an e-commerce store using ruby on rails and one of the challenging thing i find in this project is how to store all possible combinations of variants of a product.

To simplify the question question, here is a link to the post that answers to how to create multiple variants of a product. But this design has a limitation in my opinion. My worry is how to save a variant of a product that is a combination of all attributes attached to a product.

For instance how to create a variant that is of color red and of size medium at the same time whereas color and size are the attributes attached to a product. Any advices and suggestions are welcome. Thanks in advance.

Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786
Hassaan
  • 1
  • 1
  • I'm confused. What is the difference between a variant and an attribute? – Gordon Linoff Oct 14 '17 at 16:35
  • Attributes are options that can be attached to a product and later the combination of these **options_values** lead to different variants of a product. For instance we have the following options/attributes `color and waist-size` along with the values `red,blue,white` & `32,34,36` respectively. Now possible combinations of these different `attribute_values` lead to different variants of a product. For example `red:32` is a variant of a product with color red and size 32. Similarly `red:34, red:36, blue:32, blue:34 etc` are all different variants of a single product. Hope that helps. – Hassaan Oct 17 '17 at 13:09

1 Answers1

4

Approach #1

Conceptually, I think it's easiest to make each variant a separate Product. In most e-commerce applications, this makes sense - each variant would have its own SKU, and might vary on any number of different attributes: size and colour might work for t-shirts, but pants may have waist size and in-seam length, for example. So, just create a bunch of Products with the correct attributes.

However, you want variants (e.g. multiple pant sizes in the same style) to appear on the same page together. To do that, I would make a separate class (e.g. ProductGroup) that has_many :products. The ProductGroup would represent all the products appearing on the same page of your store. For many products, they might be the only Product in the ProductGroup, but for products with size / color options, you'll have more than one.

Then, your ProductPageController#show method can display a specific ProductGroup. Write some controller/view helper logic to determine which attributes are shared across the members of the ProductGroup, and display them as usual, but for any attributes that are not shared, make a <select> or something similar to choose those attributes.

Approach #2

If you want to make a single Product that contains all the variants, you'll need to deal with the fact that varying attributes may be different for every product. The easiest way to do that would be to store varying attributes as a serialized hash. For example, if your database is PostgreSQL, I've had very good success using the jsonb column type. This would allow you to do something like this (if you had a jsonb column on your Product model called variants:

tshirt = Product.new
tshirt.variants = { size: ["S", "M", "L", "XL"], color: ["red", "blue"] }
pants = Product.new
pants.variants = { inseam: ["30", "32", "34", "36", "38"], waist: ["30", "32", "34", "36", "38"] }

Then, if you want to find out (in your controller) what the attributes are that could vary, you can just do:

tshirt.variants.keys  # ["size", "color"]
pants.variants.keys   # ["inseam", "waist"]

So, at the controller/view levels, you'd just need to iterate through those keys and generate a UI (e.g. <select>) for each key.

For more information on using PostgreSQL's jsonb in Rails, you can check out this tutorial (especially the section entitled "How Can I Do this in Rails"). There is also MySQL's json data type, or you can check out Rails' serialize method.

drosboro
  • 447
  • 2
  • 8