ruby-on-railsrubymetadata

Add custom fields to object in ROR application


I'm working on CRM platform.

I would like my users to add, edit and delete custom fields in Client, Contact and Lead objects. Those fields may be plain textfield, list, checkbox, tag etc. Those fields may be required or not. Those fields may have custom validation (that user will define).

Say one company from financials would like to add income to Client object, another would add order configuration to Lead object.

Is there any "enterprise-level" solution (ROR gem) for my problem.

Of cause I know about Custom configuration and config gem, but it doesn't look extensible enough.


Solution

  • Hard question, but this is how I would try to deal with it: I would make all the objects to be derived from a CustomField object, then I would create a one to many relationship between it and a Field model. Something like this:

    create_table :field_types do |t|
      t.string :name  # This would identify the fields: checkbox, plain text, etc
    end
    
    create_table :fields do |t|
      t.belongs_to :custom_field, null: false, index: true
      t.belongs_to :field_type, null: false, index: true
      t.string :name
    end
    
    class Field < ApplicationRecord
      belongs_to :custom_field
      belongs_to :field_type
    end
    
    class CustomField < ApplicationRecord
      has_many :fields
    end
    

    This way you could just look into the specified fields on the database and mount it at the view.

    Then I would create a table for each type of field that could be used by the users to save the data from the CustomField objects. For instance, I would check the Client field specifier, mount a view with checkboxes A and B. Then, I would get the data from the checkboxes and save each of them at the table Checkboxes with an identifier, so that I could tell that it came from clients.

    Depending on what you need to do, another idea that pops to my head is to save the data as a JSON string into the database. This way you could have different fields with different values, all you would need to do is serialize and deserialize to save and load it from the database, respectively.

    Sorry if it was a little confusing. Hope it helps.