我正在使用ActiveSupport :: Concern来清理我的AR类中包含的一些代码。我有一个模块用于计算数据上的下威尔逊:
module CalculateWilsonBound
extend ActiveSupport::Concern
included do
class_attribute :wilson_ratings
class_attribute :wilson_positive_ratings
end
def calculate_wilson_lower_bound
number_of_ratings = self.class.wilson_ratings.call(self)
...
end
end
在我将它包含在一个对象之后,我想提供两个类级别的方法(wilson_ratings,wilson_positive_ratings),这些方法定义了将返回各自计数的块。
从AR对象的角度来看:
class Influence < ActiveRecord::Base
include CalculateWilsonBound
wilson_ratings { |model| model.votes }
wilson_positive_ratings { |model| model.positive_votes }
这不会导致任何运行时错误,但是当我访问class属性时:
number_of_ratings = self.class.wilson_ratings.call(self)
nil 。
首先,我是否组织了一个有意义的代码,其次,为什么class属性为nil?
答案 0 :(得分:2)
我相信你需要这样做:
class Influence < ActiveRecord::Base
include CalculateWilsonBound
self.wilson_ratings = Proc.new { |model| model.votes }
self.wilson_positive_ratings = Proc.new { |model| model.positive_votes }
end
目前你有2个问题。
当尝试在类定义的上下文中分配类属性时,Rails将不会意识到您引用的是class属性,除非您使用self.
您需要分配class属性,而不是将块传递给它。正如您的代码现在读取的那样,您看起来正在调用一个名为wilson_ratings
的方法并将一个块传递给它。
至于你的代码是否合情合理,它开始让我觉得有点好笑。我更喜欢可能的服务类模式(参见http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/) - 它可以防止你不得不乱用class_attributes和其他潜在的毛茸茸的概念。
答案 1 :(得分:0)
如果要使类属性可调用,可以为其分配proc
self.wilson_ratings = proc{ |model| model.votes }