Ruby on rails Rails3动态添加虚拟属性

Ruby on rails Rails3动态添加虚拟属性,ruby-on-rails,ruby,ruby-on-rails-3,activerecord,Ruby On Rails,Ruby,Ruby On Rails 3,Activerecord,我的设置:Rails 3.0.9、Ruby 1.9.2 我有这样做的理由,但我需要的是一种向activerecord结果集动态添加虚拟属性的方法。这意味着我没有在模型中使用attr\u accessor,而是希望动态地将虚拟属性添加到结果集 比如说, users = User.all #a user has following attributes: name, email, password 我想做的是(不使用attr\u accessor)向用户添加一个虚拟属性status,这可能吗?您应

我的设置:Rails 3.0.9、Ruby 1.9.2

我有这样做的理由,但我需要的是一种向activerecord结果集动态添加虚拟属性的方法。这意味着我没有在模型中使用
attr\u accessor
,而是希望动态地将虚拟属性添加到结果集

比如说,

users = User.all
#a user has following attributes: name, email, password
我想做的是(不使用
attr\u accessor
)向
用户添加一个虚拟属性
status
,这可能吗?

您应该这样做:

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

您可以执行以下操作:

添加一个属性“extras”,该属性将作为散列访问,并将存储任何附加/动态属性——然后告诉Rails通过ActiveRecord或Mongo中的JSON或您使用的任何东西来持久化该散列

e、 g:

您还可以为用户模型添加一点魔力,以便在获得方法_missing()调用时查看extras哈希

另见:
谷歌“Rails 3 serialize”

如果您的属性是只读的,您也可以通过在数据库查询中选择它们来添加它们。SQL结果中出现的字段将自动添加为属性

示例:

User.find_by_sql('users.*, (...) AS status')
User.select('users.*, joined_table.status').join(...)
通过这些示例,您将拥有所有
User
属性和一个附加的
status
属性。

您可以简单地执行以下操作:

users.each { |user| user.class_eval { attr_accessor :status } }

所有
用户
将拥有
用户状态
用户状态=:新状态
可用。

这不起作用,因为此属性不会在database@Tilo:你显然不知道什么是虚拟世界attribute@Tilo:您将看到虚拟属性不应保存在中database@Tilo:他的问题是:动态设置一个
attr\u访问器
,非常清楚。你介意把你那可笑的-1拿走吗?当然,我对那个铁路司机很熟悉。如果您只是暂时需要一个虚拟属性,例如表单字段,这会有所帮助。但是,如果您想拥有一个真正的动态持久化属性,它将无法工作。问题是,其他会话可能会修改记录,从而修改动态属性的值,但它不会被持久化,并且这些值可能会在会话之间有所不同。另外:本地记录的状态可能会变得过时。这要看鲍勃想要什么了。。。如果他只需要非持久化的临时属性,那么你的答案是完美的。你在这里没有定义
attr\u访问器
行为。重读Bob的问题-他明确表示他不想使用attr\u访问器他说他不想在模型中设置
attr\u访问器
,这是完全不同的你的散列没有虚拟的。我不是说你的回答不好,只是你对我的判断是不合理的
   u = User.find 3

   u.extras[:status] = 'valid'
   u.save
User.find_by_sql('users.*, (...) AS status')
User.select('users.*, joined_table.status').join(...)
users.each { |user| user.class_eval { attr_accessor :status } }