我的设置:Rails 3.0.9,Ruby 1.9.2
我有理由这样做,但我需要的是一种动态添加虚拟属性到activerecord结果集的方法。这意味着我没有在模型中使用attr_accessor
,而是希望动态地将虚拟属性添加到结果集中。
例如,
users = User.all
#a user has following attributes: name, email, password
我喜欢说的是添加(不使用attr_accessor
)虚拟属性status
到users
,这可能吗?
答案 0 :(得分:15)
你应该这样做:
users.each do |user|
user.instance_eval do
def status
instance_variable_get("@status")
end
def status=(val)
instance_variable_set("@status",val)
end
end
end
答案 1 :(得分:2)
您可以执行以下操作:
添加一个属性“extras”,它将作为Hash访问,并将存储任何其他/动态属性 - 然后告诉Rails通过ActiveRecord或Mongo中的JSON或您使用的任何内容来持久化Hash
e.g:
class AddExtrasToUsers < ActiveRecord::Migration
def self.up
add_column :users, :extras, :text # do not use a binary type here! (rails bug)
end
...
end
然后在模型中添加一个语句来“序列化”该新属性 - 例如这意味着它被持久化为JSON
class User < ActiveRecord::Base
...
serialize :extras
...
end
您现在可以执行此操作:
u = User.find 3
u.extras[:status] = 'valid'
u.save
你还可以为User模型添加一些魔法,如果它获得method_missing()调用,则查看额外的Hash
另见: 谷歌“Rails 3序列化”
答案 2 :(得分:1)
如果您的属性是只读的,您也可以通过在数据库查询中选择它们来添加它们。出现在SQL结果结果中的字段将自动添加为属性。
示例:
User.find_by_sql('users.*, (...) AS status')
User.select('users.*, joined_table.status').join(...)
通过这些示例,您将拥有所有User
个属性和一个额外的status
属性。
答案 3 :(得分:1)
你可以这样做:
users.each { |user| user.class_eval { attr_accessor :status } }
所有users
都有user.status
和user.status = :new_status
可用。