我有一个SaaS应用程序,帐户想要在用户模型上保存不同类型的信息。例如,一个帐户可能希望保存年龄和生日,但在另一个帐户中,他们不会使用这些列,并且希望保存关于头发颜色和身高的信息。Rails:模型上的动态列/属性?
这些仅仅是一些例子,但我如何构建我的模型和数据库,以便它可以很好地适用于“定制的,动态的”列而不会创建太多的空属性。
我有一个SaaS应用程序,帐户想要在用户模型上保存不同类型的信息。例如,一个帐户可能希望保存年龄和生日,但在另一个帐户中,他们不会使用这些列,并且希望保存关于头发颜色和身高的信息。Rails:模型上的动态列/属性?
这些仅仅是一些例子,但我如何构建我的模型和数据库,以便它可以很好地适用于“定制的,动态的”列而不会创建太多的空属性。
对我来说,这个声音就像一个完美的例子,你想使用一个无模式的NoSQL数据库。或者(如果你想坚持SQL),你可以有一个基地User
模型与has_many :attributes
协会。其中一个属性只是key
('年龄','生日','头发颜色')和一个值的组合。复杂性来自不同的数据类型和同时涉及多个属性的查询。
你的模式可能是这样的:
create_table "accounts", :force => true do |t|
t.integer "user_id"
t.string "data_key"
t.string "data_value"
end
Account模型
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'
=>将设置头发的颜色
如果用户属于多个帐户,此代码是否会更改?并且帐户会选择他们是否想要支持某个data_key,并且该帐户中的用户将拥有这些data_keys上的data_values – kibaekr 2014-09-26 00:29:42
我收到此错误:“NoMethodError:undefined method find_by_data_key for#
@ kibaekr,用户模型具有'has_many:accounts'并且'find_by_data_key'方法不是针对'User'对象,而是针对'Account'模型。 – shweta 2014-09-26 05:08:56
以下是两个选项。 1. NoSQL数据库。 2. Rails 4 Store功能。
Rails Store看起来非常有趣,适用于许多您希望坚持使用常用数据库和模型的情况,以及“当您不关心能够在单个记录的上下文之外查询该商店时” - 引用文档。适合我。 – DannyB 2015-12-16 12:21:12
如果你使用PostgreSQL,你可以看看hstore那么你可以保存信息序列化,实际上你可以对这些哈希一些疑问BTW轨道4,5已经包括此功能,但如果您使用的是旧版本的Rails你可以包含这个宝石。 https://github.com/diogob/activerecord-postgres-hstore在你的Gemfile中,你应该可以像下面这样开始播放:
user = User.new
user.preferences = {
email: "[email protected]",
github: "heridev"
}
user.save!
user.reload
# Searching
User.where("preferences @> hstore(:key, :value)", key: "email", value: "[email protected]").first
jc,你最终会在哪里用这个? – mmcrae 2015-03-04 14:52:40
@mmcrae我结束了使用postgresql的.json数据结构,并将任何自定义列转储到此.json数据字段中。 – kibaekr 2015-03-05 09:37:43