Dynamic Fields (attributes)

Hello!

I am looking for a plugin or at least the way how to realize dynamic fields in a model.

Why I need: I want to create a product catalog application, each type of product can have different set of fields (e.g. computer, mobile phone, vacume cleaner and etc.). Requirements:    1. Set of fields with types can be defined from admin panel foreach product type    2. Validation should be presented    3. It should be possible to sort and filter on this fields    4. It should be possible to auto-generate forms for products

All plugins that i found does not give me this functionality.

Who can advise me something or point to a plugin?

I'm actually doing something like this right now. My example is a lot more complex because there need to be various depths and not every attribute is in fact an attribute, but some are a set of options, but basically I can point you in the right direction:

Your catalog consists of products, so you'll have a model Product. They will have attributes, so you'll have a model ProductAttribute. Then you'll need a table that links them together. Name it anything you'd like, I chose ProductDefinition. Then, in the corresponding models do:

class Product < ActiveRecord::Base   has_many :product_definitions   has_many :product_attributes, :through => :product_definitions end

class ProductAttribute < ActiveRecord::Base   has_many :product_definitions   has_many :products, :through => :product_definitons end

class ProductDefinition < ActiveRecord::Base   belongs_to :product   belongs_to :product_attribute end

Now you can use eager loading to define a product:

@product = Product.find(:first)

And do @product.attributes to get all the product's attributes.

Hope this helps!

Kind regards, Jaap Haagmans w. http://www.relywebsolutions.nl

Thank you Jaap!

I thought about it previousely, but one problem exists with with validation and strong types of attributes. As i understand ProductAttribute should have several number of fields for different types of values e.g. string, decimal, integer, boolean and etc. And there should be an accessor wich will give us value from field dependent on type wich was defined in ProductDefinition. Am I right?

May be we can collaborate over this problem?

Thank you Jaap!

I thought about it previousely, but one problem exists with with validation and strong types of attributes. As i understand ProductAttribute should have several number of fields for different types of values e.g. string, decimal, integer, boolean and etc. And there should be an accessor wich will give us value from field dependent on type wich was defined in ProductDefinition. Am I right?

I have had a very long day and I now see that I may have misunderstood: you might not even need a many-to-many relation, am I right? There's always the possibility of just using has_many and belongs_to between the product and attribute table. Especially if you want to be able to, for example, destroy a product and its attributes, you don't want to care too much about double entries.

As for the string, integer, boolean etc.: that's true. There are a few methods that come to mind and the first one is indeed creating fields for all these possibilities and just looking which field contains a value. You can evaluate whether it's a string, a boolean or an integer using the field it's in. However, I'm unsure whether that's the most robust solution. You could also store every value as a string and convert it back in your model.

May be we can collaborate over this problem?

Sure, you can always contact me directly, but I'm no expert yet, I'm probably as much in the learning process as you are and the Rails community you've found here is full of true experts. Let's have my responses be evaluated by the community instead of taking them for truth. That way we can both learn.

I think convert from string is not a good solution, because we will not be able to use WHERE and ORDER BY queries over attributes (e.g. ORDER BY string and number is strongly different). Also I think we need some kind of Query Builder e.g. :orderby => "# {attriDef.field}" or :condition=> "#{attriDef.field} = ?". "attriDef.field" should return a field name dependent on attribute type.

I think convert from string is not a good solution, because we will not be able to use WHERE and ORDER BY queries over attributes (e.g. ORDER BY string and number is strongly different).

Yup, that's true. You can of course let Rails do part of the work for your database, but you don't want to retrieve rows you don't need of course, so it's probably not the way to go.

Also I think we need some kind of Query Builder e.g. :orderby => "# {attriDef.field}" or :condition=> "#{attriDef.field} = ?". "attriDef.field" should return a field name dependent on attribute type.

Well, you know what you're looking for, right? If you're comparing an integer to values in your table, you know you're looking for an integer. I'm pretty sure Rails can do that for you.

I don't know about autogeneration of forms, but it seems to me that what you want is a polymorphic association, where you have a model that contains common attributes, and specific models with a specified set of attributes. Does this answer your question ?

   ngw

Hello,

No. I need a system where attributes of model can be defined from admin panel dynamically. So I should be able to add and remove fields of models. E.g. I have 2 kinds of products mobile phones and cars. Each type has own set of attributes. Also user should be able to sort and filter model by this fields.