2011-09-01 63 views
9

我的设置:Rails的3.0.9,1.9.2红宝石Rails 3中添加虚拟属性动态

我有我的理由这样做,但我需要的是一个虚拟的属性动态添加一个ActiveRecord的结果集的方式。这意味着我没有在模型中使用attr_accessor,而是希望将虚拟属性动态添加到结果集中。

例如,

users = User.all 
#a user has following attributes: name, email, password 

我喜欢做的是说加(不使用attr_accessor)虚拟属性statususers,这可能吗?

回答

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 
+0

这是行不通的,因为这个属性不会在数据库中持久 – Tilo

+6

@Tilo:你显然不知道什么是虚拟属性 – apneadiving

+0

@Tilo:http://railscasts.com/episodes/16-virtual -attributes你会看到一个虚拟属性不应该被保存在数据库 – apneadiving

2

,你可以做到以下几点:

添加属性“临时演员”,这将作为一个哈希来访问,并且将存储任何额外的/动态属性 - - 然后告诉Rails通过JSON坚持认为散列的ActiveRecord或蒙戈或任何你使用

如:

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 

您也可以加一点魔法的用户模型,看演员哈希如果它得到了method_missing ()调用

参见: 谷歌“Rails 3中连载”

+0

你没有在这里定义'attr_accessor'行为。 – apneadiving

+0

重读Bob的问题 - 他明确表示他不想使用attr_accessor – Tilo

+0

他说他不想在模型中设置'attr_accessor',这是非常不同的 – apneadiving

1

如果你的属性是只读的,你也可以在你的数据库QUER选择它们来进行添加年。出现在SQL结果结果中的字段将自动添加为属性。

例子:

User.find_by_sql('users.*, (...) AS status') 
User.select('users.*, joined_table.status').join(...) 

这些例子你就会有一切User属性和附加属性status

1

你可以简单地做:

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

所有users将有user.statususer.status = :new_status可用。