2

考虑一个模型用户:在Rails模型中“重载”一个字段的最佳方式是什么?

User(id: integer, name: string, email: string, status: string) 

当我构建的应用程序,地位是在数据库中的字段。但是新的需求意味着更改,以便在某些情况下动态计算状态。例如,在星期日,如果他们的姓氏以A开头,那么他们的状态是“不好”。

我想类似以下封装在用户模式这一功能:

Class User < ActiveRecord::Base 

    def status 
    if is_sunday && last_name.starts_with('A') 
     return 'not ok' 
    else 
     return status 
    end 
    end 

end 

什么是做到这一点的最好方法是什么?如果上面的代码确实有效,那么使用方法覆盖数据库中的字段似乎是不好的做法。

另外,我可以创建一个方法get_status使用上面的代码。但在这种情况下,我需要在整个应用程序中更改对status的每个引用。这听起来不太好。

+2

fwiw,我完全可以用这种方法作为解决方案。我认为添加'get_status'更令人困惑,因为您有点创建第二种检索用户状态的方法。 – thewillcole 2012-04-06 22:21:10

回答

4

我在ActiveRecord::Base documentation看到你可以覆盖ActiveRecord提供的默认访问器。当然,您不能像使用status那样使用它,因为它使该方法有些递归。

如果您愿意,可以使用read_attribute(:attribute_name)self[:attribute_name]来访问DB中的列值。所以长话短说,你的访问者变为:

Class User < ActiveRecord::Base 
    def status 
    if is_sunday && last_name.starts_with('A') 
     'not ok' 
    else 
     read_attribute(:status) 
    end 
    end 
end 

更新:我已经试过它和它的作品,但要注意,因为如果你不调用这个方法,明确你的数据库内容为...例如,您尝试查询users表以找到具有status = "not ok"的用户,您可能会有惊喜。

+1

在Rails 3.2上,''read_attribute(:status)'用'super'代替了吗? – Zabba 2012-04-07 05:10:57

+0

'super'应该可以在之前的Rails版本中工作,因为它是Ruby的关键,但在这种情况下,对我来说似乎有点模糊。我宁愿明确表达这一点。 – 2012-04-07 15:39:03

+1

+1,是否需要返回声明? – stephenmurdoch 2012-04-07 16:02:33