ActiveSupport ::关注和类方法

时间:2013-05-31 08:03:38

标签: ruby-on-rails ruby

我正在使用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?

2 个答案:

答案 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个问题。

  1. 当尝试在类定义的上下文中分配类属性时,Rails将不会意识到您引用的是class属性,除非您使用self.

  2. 您需要分配class属性,而不是将块传递给它。正如您的代码现在读取的那样,您看起来正在调用一个名为wilson_ratings的方法并将一个块传递给它。

  3. 至于你的代码是否合情合理,它开始让我觉得有点好笑。我更喜欢可能的服务类模式(参见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 }