我正在使用CRM平台。
我希望我的用户在Client
,Contact
和Lead
个对象中添加,修改和删除自定义字段。这些字段可以是纯文本字段,列表,复选框,标记等。这些字段可能是必需的或不是。这些字段可能具有自定义验证(用户将定义)。
假设一家财务公司希望将收入增加到Client
个对象,另一家公司会将订单配置添加到Lead
个对象。
是否有任何"企业级"解决方案(ROR gem)解决我的问题。
我之所以知道Custom configuration和config gem,但它看起来并不具备可扩展性。
答案 0 :(得分:6)
很难回答,但这就是我试图处理它的方法:我会将所有对象从CustomField
对象派生出来,然后我会在它和{{{}}之间创建一对多关系{1}}模型。像这样:
Field
这样您就可以查看数据库中的指定字段并将其挂载到视图中。
然后,我将为每种类型的字段创建一个表,用户可以使用该表来保存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
个对象的数据。例如,我会检查客户端字段说明符,使用复选框A和B安装一个视图。然后,我将从复选框中获取数据,并使用标识符将每个数据保存在表CustomField
中,以便我可以说它来自客户。
根据您的需要,我想到的另一个想法是将数据作为JSON字符串保存到数据库中。这样,您可以使用具有不同值的不同字段,所有您需要做的就是序列化和反序列化以分别从数据库中保存和加载它。
对不起,如果有点混乱。希望它有所帮助。
答案 1 :(得分:3)
假设您的数据库是关系型的:
我建议使用实体 - 属性 - 值模式: https://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model
这是一个宝石: https://github.com/iostat/eav_hashes
如果您考虑更改数据库,面向文档的数据库(如 MongoDB )也是一个选项。它是无模式的,因此您可以为不同的实例使用不同的属性。
答案 2 :(得分:1)
我不知道有任何可用的开箱即用选项,但无论如何你可能最好还是选择这样的东西。它将为您提供更大的灵活性,并且实现起来不应该太糟糕。在模型方面,我可能会为字段使用单表继承表,可能使用jsonb
列来定制选项(假设是postgres):
create_table :fields do |t|
t.string :type, null: false # TextField, ListField, etc.
t.jsonb :config, default: {}, null: false
t.belongs_to :contact
end
然后,您可以根据需要为不同的用例子类化:
class Field < ApplicationRecord
belongs_to :contact
end
class TextField < Field
def required=(required)
config[:required] = required
end
end
class CheckboxField < Field
def default_checked=(default_checked)
config[:default_checked] = default_checked
end
end
您可以查看jsonb_accessor
之类的内容,以便为jsonb列提供更清晰的界面。
同样,单表继承看起来也可能对联系人也有意义,不确定基表应该是什么,但可能是这样的:
create_table :contacts do |t|
t.string :type, null: false # Contact, Lead, Client
end
class Contact < ApplicationRecord
end
class Lead < Contact
end
答案 3 :(得分:0)