0

I have a Product model with the following columns:

name:string
price:integer

I also have a cart model, line_item model, an orders controller: pretty basic but you get the idea.

What I need to do (and have done) is add size (since it's for tshirts) and color to the Product model. Fair enough,

rails g migration AddSizeToProducts size:string

works just fine and similarly for color.

The way the buying process is set up is as follows:

  1. select shirt (one page)

  2. after selecting shirt, takes you to next page

  3. on this page, you will select both the color and size for the shirt.

From what I've gathered, using select will not be tied to the database, so I suppose collection_select would be more appropriate here? Or would something like this be OK?

<%= select @product, :id, [ ["Small",1], ["Medium",2], ["Large",3]] %>

Also, how would I "prepopulate" these fields with sizes ie small/med/large and colors ie black/blue/white without having them associated to a particular product before a product is selected (from step 1 above)?

Any input on the matter is appreciated.

Amith
  • 6,818
  • 6
  • 34
  • 45
Nubtacular
  • 1,367
  • 2
  • 18
  • 38

1 Answers1

1

without having them associated to a particular product

This confused me - surely you'd want to associate the select box with a particular product's options?


I would personally make sure the "buy process" is set up to pass the product ID throughout. I'd do this by using a nested resource in the routes:

#config/routes.rb
resources :products do
    get :step2 #-> /products/1/step2
end

This will pass params[:product_id] through the process, allowing you to use it on your next step:

#app/controllers/products_controller.rb
def step2
    @product = Product.find(params[:product_id])
end

#app/views/products/step2.html.erb
<%= collection_select(:product, :size_id, @product.size, :id, :name, prompt: true) %>

Having looked at it, I think your real problem is storing your size as a string inside your Product model. I'd make a separate model called sizes, and then use a join model called products_sizes to allow you to associate as many sizes as you need with each product. You'd then be able to call the associative data


Why not do this:

#app/models/product.rb
Class Product < ActiveRecord::Base
    has_many :product_sizes
    has_many :sizes, through: :product_sizes
end

#app/models/size.rb
Class Size < ActiveRecord::Base
    has_many :product_sizes
    has_many :products, through: :product_sizes
end

#app/models/product_size.rb
Class ProductSize < ActiveRecord::Base
    belongs_to :product
    belongs_to :size
end

This allows you to store sizes for many different products, allowing you to pick ID's from the ProductSize model, referencing them directly in your cart model:

#app/models/cart.rb
Class Cart < ActiveRecord::Base
    belongs_to :user
    belongs_to :product
    belongs_to :product_size
end

#carts
id | user_id | product_id | product_size_id | created_at | updated_at

This means if you create a new cart item, you'll be able to assign a product's size to the record directly:

<%= collection_select(:product, :product_size_id, @product.sizes, :id, :name, prompt: true) %>
Richard Peck
  • 76,116
  • 9
  • 93
  • 147