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

それをオブジェクトに含めた後、それぞれのカウントを返すブロックを定義する 2 つのクラス レベル メソッド (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)

ゼロです。

まず第一に、私は理にかなった方法でコードを整理していますか?第二に、なぜクラス属性が nil なのですか?

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 に答える