2

search doSunspotブロックの共通コードを、複数の場所から呼び出せるメソッドにリファクタリングするにはどうすればよいですか? これは Sunspot 固有の問題というよりも、おそらく Ruby のメタプログラミングに関する問題だと思いますが、ここまでです。

次のように黒点を使用するモデルがあります。

class Book
  def self.basic_search(params)    
    search do
      # boilerplate...
      facet :category
      paginate page: params[:p], per_page: APP_CONFIG[:results_per_page]

      # bespoke basic_search search code goes here
    end    
  end

  def self.curated_search(params)    
    search do
      # boilerplate...
      facet :category
      paginate page: params[:p], per_page: APP_CONFIG[:results_per_page]

      # bespoke curated_search code goes here
    end    
  end

end

次に、次のようにコードをリファクタリングしようとします。

class Book
  def self.basic_search(params)    
    search do
      boilerplate params
      # bespoke basic_search search code goes here
    end    
  end

  def self.curated_search(params)    
    search do
      boilerplate params
      # bespoke curated_search code goes here
    end    
  end

  def self.boilerplate(params)
    facet :category
    paginate page: params[:p], per_page: APP_CONFIG[:results_per_page]
  end

end

ボイラープレート メソッドは Book のクラス メソッドとして定義されているため、当然のことながら、次のようになります。

undefined method 'boilerplate' for #<Sunspot::DSL::Search:0x007f92b4177a98

の使用instance_evalが必要だと思われますが、Ruby を初めて使用するので、それを適用する方法がよくわかりません。

4

2 に答える 2

2

これが私が思いついたものです。

def self.basic_search(params)    
  search do
    boilerplate(self, params)  # here, self is a sunspot search instance

    # bespoke basic_search search code goes here
  end    
end

def self.curated_search(params)    
  search do
    boilerplate(self, params)  # here, self is a sunspot search instance

    # bespoke curated_search code goes here
  end    
end

def self.boilerplate(sunspot, params)
  sunspot.instance_eval do 
    facet :category
    paginate page: params[:p], per_page: APP_CONFIG[:results_per_page]
  end
end
于 2012-10-09T17:19:36.400 に答える
0

Book.boilerplate特定の問題を修正するには、代わりに呼び出すようにスコープを設定してみてください。エラーメッセージが示すように、search'sdo...endブロック内のコンテンツは、内部Sunspot::DSL::Searchではなく内部で評価されBookます。

次の例を参照してください。Foo->BookおよびBar->で読みやすくするために簡略化されていますSearch

複製のある元の方法

class Foo
  def self.bar()
    p 1
  end

  def self.baz()
    p 1
  end
end

重複排除。Bookサンスポットの例では、ここでハードコードされたパススルーを使用するのではなく、メソッド定義フックまたは同等のものを使用してメソッドを定義している可能性が高いことに注意してください。ポイントは、にあるBarを呼び出すことができるということquuxですFoo

class Foo
  # Following two methods inserted via DSL magic. #Simplified for readability.
  def self.bar
    Bar.bar
  end

  def self.baz
    Bar.baz
  end

  def self.quux()
    p 1
  end
end

class Bar
  def self.bar
    Foo.quux
  end

  def self.baz
    Foo.quux
  end
end

Searchただし、特定のケースでは、評価されるパラメータがおそらくで評価されるべきであり、ではなく評価されるべきであるという点で、これはまだあなたが望むことをしていない可能性がありますBook。paramキャッシングの方法に応じてsearch、このようなことを試すことを検討する必要があります。

def self.boilerplate(params)
  search do
    facet :category
    paginate page: params[:p], per_page: APP_CONFIG[:results_per_page]
  end
end
于 2012-10-09T17:12:44.660 に答える