Create and manage different product schema and their instances.
Ruby JavaScript
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


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


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:

  • product_types
  • product_attribute_types
  • product_attributes
  • products

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.


  • ProductType.list - returns list with available product types

  • ProductType.define(name, &block) - creates a new product type and pass the block to it

  • ProductType.of_type(type_name) - return scoped Product relation of the given type, which you can chain with #new, #create, etc

  • Product#get_dynamic_attribute(name) - return the value of given attribute

  • Product#set_dynamic_attribute(name, value) - set a value on given attribute


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


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

Then you can add additional attributes to that type:

  laptop.add_attribute(:os, :string)

or remove one:


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'}

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)

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

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