Home

Awesome

Introduction

ProductManager allow to create products with infinite number of attributes. You can add and remove attributes at any time.

Usage

This is Rails engine and is currently targeting the 3.0 versions. Include the gem and run rails g product_manager this will copy the migration file into db/migrate directory.

The migration create the following tables:

The products table has two columns created by default price and description. You should edit the migration file if you want to add or remove columns.

API

Testing

A dummy rails app lives in spec/dummy and is used to test the engine agains rails application.

rake clean will remove any migrations and data from the dummy app rake spec will install the migrations, if needed and run the specs

Examples

After you have this running, you can create new Product type with this code:

    laptop = ProductType.define :Laptop do
      has :ram, :integer
      has :display, :integer
      has :color, :string
    end

Then you can add additional attributes to that type:

  laptop.add_attribute(:os, :string)

or remove one:

laptop.remove_attribute(:color)

Then create some products:

  l = laptop.products.create :price => 10.0, :description => 'Cheap laptop'
  l.set_dynamic_attribute(:ram, '1GB')
  l.set_dynamic_attribute(:display, 13)
  l.set_dynamic_attribute(:os, 'Windows 7')

ActiveRecord's attributes interface

There is a attribute accessor for each dynamic attribute, making them work with ActiveRecord's methods like #update_attributes, #new, #create, etc.

This way the example above can be rewritten as follows:

  l.ram = '1GB'
  l.display = 13
  l.os = 'Windows 7'

Or even better:

  params[:product] = {:ram => '1GB', :display => 13, :os => 'Windows 7'}
  l.update_attributes(params[:product])

Application usage

Because every product require a type to work correctly you can manipulate products by two ways. One is to work directly with the given ProductType:

  type = ProductType.find(type_id) || ProductType.find_by_name(type_name)
  type.products.create(params[:product])

The other is by using the .of_type proxy method on the Product class:

  product = Product.of_type(params[:type]).new 
  product.update_attributes(params[:product])