2

Project モデルと Developer モデルがあります。特定の開発者向けのプロジェクトの「面白さ」を計算するという概念があります。

class Project < ActiveRecord::Base
  def interestingness_for(developer)
    some_integer_based_on_some_calculations
  end
end

Project.order_by_interestingness_for(bill)のようなものではなく、言えるようになるといいと思います。

Project.order(:interestingness, :developer => bill)

単なる関数ではなくスコープにするので、次のようなことができます

Project.order(:interestingness, :developer => bill).limit(10)

ただし、スコープをオーバーライドする方法が明らかではないため、これを行う方法はわかりません。何かアドバイス?

4

1 に答える 1

0

Project クラスに標準の ActiveRecord クエリ メソッドを使用する必要がないと仮定するとorder、他のクラス メソッドと同様にオーバーライドできます。

def self.order(type, options)
  self.send(:"special_#{type}_calculation_via_scopes", options)
end

次に、必要な計算方法を確実に作成するようにします (これは、興味や他のアルゴリズムによって異なります)。また、計算方法はスコープまたはその他の AR クエリ インターフェイス メソッドのみを使用します。クエリ インターフェイスを使用してメソッド ロジックを同等の SQL に変換することに慣れていない場合は、特定の計算に応じてメソッドを直接操作できる可能性があるSqueel DSL gem を使用してみてください。

古典的な方法が必要なorder場合 (これは通常、安全な仮定です)、オーバーライドしないでください。この目的のためにプロキシの非 ActiveRecord オブジェクトを作成するか、別の命名規則を使用してください。

どうしてもやりたい場合は、エイリアシングを使用して同様の効果を得ることができますが、Rails の進行に伴って 2 番目の引数 (この場合は「オプション」) が突然別の意味を持つようになると、長期的には意図しない結果になる可能性があります。使用できるものの例を次に示します。

def self.order_with_options(type, options = nil)
  if options.nil?
    order_without_options(type)
  else
    self.send(:"special_#{type}_calculation_via_scopes", options)
  end
end    
class << self
  alias_method_chain :order, :options
end
于 2012-10-11T16:29:27.563 に答える