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.