And*_*rew 2 ruby-on-rails metamodel ruby-on-rails-3
我希望能够将"元"信息添加到模型中,基本上是用户定义的字段.所以,举个例子,让我们想象一下User模型:
我为名字,姓氏,年龄,性别定义字段.
我希望用户能够定义一些"元信息",基本上可以进入他们的个人资料页面并分享其他信息.因此,一个用户可能想要添加"爱好","职业"和"家乡",而另一个用户可能想要添加"爱好"和"教育".
所以,我希望能够为这种东西提供一个标准视图,所以例如在视图中我可以做一些像(在HAML中):
- for item in @meta
%li
%strong= item.key + ":"
= item.value
Run Code Online (Sandbox Code Playgroud)
通过这种方式,我可以确保始终如一地显示信息,而不仅仅是向用户提供可以格式化所有不同方式的降价文本框.
我也很想能够点击meta并看到其他用户已经给出相同的东西,所以在上面的例子中,两个用户都定义了"爱好",能够说我希望看到用户是很好的有共同的爱好-甚至更好,我想看看如果用户的爱好是_ __.
因此,由于我不知道用户希望提前定义哪些字段,因此提供这种功能的选项有哪些?
是否有一个gem来处理这样的模型上的自定义元信息,或者至少有类似的东西?有没有人遇到过这种问题?如果是这样,你是如何解决的?
谢谢!
动态字段实现取决于以下因素:
通常,解决方案不能满足所有要求.迈克的解决方案优雅地解决了1和5问题.如果1和5对您很重要,您应该使用他的解决方案.
这是一个解决1,2,3,4和5的长解决方案
更新users表格
添加一个text名为metausers表的字段.
更新您的User模型
class User < ActiveRecord::Base
serialize :meta, Hash
def after_initialize
self.meta ||= {} if new_record?
end
end
Run Code Online (Sandbox Code Playgroud)
添加新的元字段
u = User.first
u.meta[:hobbies] = "skiing"
u.save
Run Code Online (Sandbox Code Playgroud)
访问元字段
puts "hobbies=#{u.meta[:hobbies]}"
Run Code Online (Sandbox Code Playgroud)
迭代元字段
u.meta.each do |k, v|
puts "#{k}=#{v}"
end
Run Code Online (Sandbox Code Playgroud)
要满足第5个要求,您需要使用Solr或Sphinx全文搜索引擎.它们比依赖DB进行LIKE查询更有效.
如果您通过Sunspot gem使用Solr,这是一种方法.
class User
searchable do
integer(:user_id, :using => :id)
meta.each do |key, value|
t = solr_type(value)
send(t, key.to_sym) {value} if t
end
end
def solr_type(value)
return nil if value.nil?
return :integer if value.is_a?(Fixnum)
return :float if value.is_a?(Float)
return :string if value.is_a?(String)
return :date if value.is_a?(Date)
return :time if value.is_a?(Time)
end
def similar_users(*args)
keys = args.empty? ? meta.keys : [args].flatten.compact
User.search do
without(:user_id, id)
any_of do
keys.each do |key|
value = meta[key]
with(key, value) if value
end
and
end
end
end
Run Code Online (Sandbox Code Playgroud)
查找类似用户
u = User.first
u.similar_users # matching any one of the meta fields
u.similar_users :hobbies # with matching hobbies
u.similar_users :hobbies, :city # with matching hobbies or the same city
Run Code Online (Sandbox Code Playgroud)
这里的性能提升很重要.
| 归档时间: |
|
| 查看次数: |
1461 次 |
| 最近记录: |