我有一个SaaS应用程序,用户想在用户模型上保存不同类型的信息。例如,一个账户可能想保存年龄和出生日期,但另一个账户不会使用这些列,并想要保存头发颜色和身高等信息。
这只是例子,但如何构建我的模型和数据库,以便它能够与“定制、动态”列很好地配合,而不会创建太多空属性呢?
我有一个SaaS应用程序,用户想在用户模型上保存不同类型的信息。例如,一个账户可能想保存年龄和出生日期,但另一个账户不会使用这些列,并想要保存头发颜色和身高等信息。
这只是例子,但如何构建我的模型和数据库,以便它能够与“定制、动态”列很好地配合,而不会创建太多空属性呢?
以下是两个选项: 1. NoSQL数据库。 2. Rails 4 Store 功能。
对我来说,这似乎是一个完美的例子,你需要使用无模式的NoSQL数据库。
或者(如果您想坚持使用SQL),您可以有一个基本的User
模型,带有一个has_many:attributes
关联。其中属性只是一个键值对的组合,包括key
(如'age','birthday','hair color')和一个值。复杂性在于不同的数据类型和同时覆盖多个属性的查询。
user = User.new
user.preferences = {
email: "p@elh.mx",
github: "heridev"
}
user.save!
user.reload
# Searching
User.where("preferences @> hstore(:key, :value)", key: "email", value: "p@elh.mx").first
你的架构可能是这样的:
create_table "accounts", :force => true do |t|
t.integer "user_id"
t.string "data_key"
t.string "data_value"
end
账户模型
belongs_to :user
DATA_KEYS = ['age', 'birthdate', 'hair_color', 'height' ] # etc..
用户模型
has_many :accounts
Account::DATA_KEYS.each do |method|
# getter method
define_method(method) do
accounts.find_by_data_key(method).try(:data_value)
end
# setter method
define_method("#{method}=") do |value|
data = accounts.find_or_initialize_by_data_key(method)
data.data_value = value.strip
data.save
end
end
您可以获取和设置帐户数据值
例如:user.age
=> 将返回用户的年龄
user.hair_color = 'brown'
=> 将设置头发颜色
has_many:accounts
,而find_by_data_key
方法不是针对User
对象的,而是针对Account
模型的。 - shwetadata_key
列位于accounts
表中而不是users
表中。 - shweta