0

I recently finished an application that was essentially an online store. I am trying to refactor the application now that I know a little more about Ruby and Rails.

I have products (laptops) that have many attributes such as screen size, processor speed, etc. Originally I just threw all the attributes into one table like:

ActiveRecord::Schema.define(version: 2013121302021398) do

  create_table "products", force: true do |t|
    t.string   "brand"
    t.string   "model"
    t.string   "processor_speed"
    t.string   "screen_size"
    .....etc, etc

However I realized it was difficult to add new features/ change the schema. Also, a lot of laptops these days do not have optical drives so that was a column (among many others) that was wasted on most units, I still had to have it in there though for the ones that did.

I thought trying to make it super dynamic by just having one column called features, and make it a hash. So I could call

@product.features[:screen][:size]
=> "15.6 inches"

Using method_missing to define attributes, the product did not have, on the fly. But it got kind of messy and I started looking for a solution that was more simple.

My next idea was to have a separate class and table for each feature, but I feel as though that would get messy as well. Also I was not sure how to build a form that would work for that.

I have spent some time trying to weigh the pro's and con's of various approaches, but I want to make sure I am doing this in the most pragmatic way possible..

What is the most common solution/approach to this problem?

Please note: I tried doing a many_to_many relationship with a features_products table. However, it was awkward trying to obtain any data..

@product.features[0][:name]
=> "screen_size"
@product.features[0][:value]
=> "15.6 inch"

is how I would have to retrieve data. I would rather call something like

@product.features.screen_size
Davey
  • 1,093
  • 1
  • 13
  • 25
  • Deleted my comments as I see you already attempted to serialize features column. This might be a good case for MongoDB. – Damien Roche Dec 13 '13 at 05:47
  • That's the problem with a serialized column, you'd have to manually loop through the hash keys and create relevant form fields, then piece it together on the backend (and validate keys). – Damien Roche Dec 13 '13 at 05:48
  • Right, but since there is no "screen_size" attribute directly on the Product model how would I set that up so I can still validate the params and not end up with an "undefined method" error. Since I can't just say <%= text_field :screen_size %> ..That is the main issue I ran into.. – Davey Dec 13 '13 at 05:50
  • Yeh, it's not ideal. You'd have to create custom form fields not tied to the model. Here's an example: http://stackoverflow.com/questions/9613208/serialized-hash-field-and-simple-form – Damien Roche Dec 13 '13 at 05:52
  • Yes! I think this is what I have been looking for. Post it as an answer if you want credit. Thanks! – Davey Dec 13 '13 at 05:54

1 Answers1

1

One solution is to go ahead with your serialized features column. Here's an example of how to implement the form: Serialized Hash field and Simple Form.

Community
  • 1
  • 1
Damien Roche
  • 13,189
  • 18
  • 68
  • 96