如何将Sunspot search do
块中的公共代码重构为可以从多个位置调用的方法?我怀疑这可能更像是一个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不熟悉我不太清楚如何应用它。
答案 0 :(得分: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
答案 1 :(得分:0)
要解决具体问题,请尝试使用范围来调用Book.boilerplate
。如错误消息所示,search
do...end
块内的内容在Sunspot::DSL::Search
内评估,而不是在Book
内评估。
请参阅以下示例。简化了Foo
- >的可读性Book
和Bar
- &gt; Search
原创方式w / duplication
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
进行评估。根据{{1}}进行param缓存的方式,你应该考虑尝试这样的事情。
search