1

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

这不会导致任何运行时错误,但是当我访问类属性时:

number_of_ratings = self.class.wilson_ratings.call(self)

它是

首先,我是否以有意义的方式组织代码,其次,为什么类属性为零?

4

2 回答 2

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 不会意识到您指的是类属性,除非您使用self.

  2. 您需要分配类属性,而不是将块传递给它。正如您的代码现在读取的那样,您似乎正在调用一个被调用的方法wilson_ratings并将一个块传递给它。

至于你的代码是否合理,我开始觉得有点好笑。在可能的情况下,我更喜欢服务类模式(请参阅http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/) - 它可以防止您拥有搞乱 class_attributes 和其他潜在的毛茸茸的概念。

于 2013-05-31T08:51:54.947 回答
0

如果要使类属性可调用,可以为其分配一个过程

self.wilson_ratings = proc{ |model| model.votes }
于 2013-05-31T08:48:59.213 回答