2.0.0p247 :022 > @post.title
=> "Breakfast Burrito"
2.0.0p247 :023 > solr = Refinery::Books::Book.search { fulltext @post.title.split(' ').join(' OR ') }
NoMethodError: undefined method `title' for nil:NilClass
from (irb):23:in `block in irb_binding'
from /usr/local/rvm/gems/ruby-2.0.0-p247@bk_development/gems/sunspot-2.1.0/lib/sunspot/util.rb:208:in `instance_eval'
有些东西我没有接受。 FYI fulltext
是一种方法而不是哈希,search
采用块,而不是哈希。
这有效......
2.0.0p247 :026 > solr = Refinery::Books::Book.search { fulltext 'burrito' }
SOLR Request (13.9ms) ...
答案 0 :(得分:3)
传递给.search
的块可以在BasicObject#instance_eval
之类的(instance_exec
,class_eval
,class_exec
)方法的帮助下,在不同的上下文中进行评估,以便可以从块中看到为fulltext
(可能是instance_eval
?)的接收者定义的方法Refinery::Books::Book
(以及其他DSL方法)。这里的神奇之处在于Ruby会更改块内的self
绑定。 instance_eval
的接收者在那里充当self
。
实例变量分辨率还取决于self
。当您引用@post
时,实际上是在获取@post
的实例变量self
。由于self
的上下文已在块中修改,而实际的self
没有实例变量@post
,因此nil
将作为默认值返回。
修复程序将@post.title
分配给局部变量,并在.search
块中使用该变量。
title = @post.title
solr = Refinery::Books::Book.search { fulltext title.split(' ').join(' OR ') }
该块将捕获其定义位置的本地绑定。在块中,Ruby将首先在本地绑定中查找名称,如果缺少,它将查找在self
上定义的方法。