如果您查看查询,@bot_client_id
是一个具有相同值string
的字符串。但是,当我将它们作为查询的一部分使用时,我会得到不同的结果。
为什么?
[24] pry(#<BotResponse>):1> string
=> "aiaas-1409611358153-user-0149"
[25] pry(#<BotResponse>):1> @bot_client_id
=> "aiaas-1409611358153-user-0149"
[26] pry(#<BotResponse>):1> Event.where.has{(status == 'active') & (bot_client_id == @bot_client_id)}
=> []
[27] pry(#<BotResponse>):1> Event.where.has{(status == 'active') & (bot_client_id == string)}
=> [#<Event:0x0000000464d120
id: 22,
bot_client_id: "aiaas-1409611358153-user-0149",
keyword: "gratitude",
topic: nil,
status: "active",
channel: "telegram",
created_date: 2017-05-09 15:56:51 UTC,
tickle_expression: "daily",
time_of_day: "7:00 am",
next_occurrence: 2017-05-14 14:00:00 UTC,
time_zone: "America/Los_Angeles",
recurring: true>,
#<Event:0x0000000464cfb8
id: 23,
bot_client_id: "aiaas-1409611358153-user-0149",
keyword: "daily_check",
topic: nil,
status: "active",
channel: "telegram",
created_date: 2017-05-10 04:25:47 UTC,
tickle_expression: "daily",
time_of_day: "9:00 am",
next_occurrence: 2017-05-14 16:00:00 UTC,
time_zone: "America/Los_Angeles",
recurring: false>]
答案 0 :(得分:2)
查看您的代码:
Event.where.has{(status == 'active') & (bot_client_id == @bot_client_id)}
has
占用了status
和bot_client_id
被调用的区块。这两种方法似乎不太可能在外部环境中定义。
让我们看看当我们尝试使用未定义的变量调用块时会发生什么:
>> def method_calling_block
| yield
| end #=> :method_calling_block
>> method_calling_block { abcd }
NameError: undefined local variable or method `abcd' for main:Object
from (irb):44:in `block in irb_binding'
from (irb):40:in `method_calling_block'
from (irb):44
from /Users/fylooi/.rvm/rubies/ruby-2.1.4/bin/irb:11:in `<main>'
如果我们不打电话给该区块:
>> def method_without_calling_block
| end #=> :method_without_calling_block
>> method_without_calling_block { abcd } #=> nil
看起来传递到块中的变量仅在处理块时进行评估(通常使用yield
或block.call
)。看起来这个块没有按正常方式处理。
一些谷歌搜索显示.where.has{}
是属于的方法
BabySqueel。 BabySqueel文档指出:
BabySqueel的块使用instance_eval,这意味着您无法访问实例变量或方法。
https://github.com/rzane/baby_squeel/blob/master/lib/baby_squeel/dsl.rb
中的相关方法似乎为evaluate
module BabySqueel
class DSL < Relation
def evaluate(&block)
if block.arity.zero?
instance_eval(&block)
else
yield(self)
end
end
end
end
这意味着在
的上下文中Event.where.has{(status == 'active') & (bot_client_id == @bot_client_id)}
@bot_client_id
在接收者的绑定(这是BabySqueel::DSL
个对象)中进行评估,而不是在调用者的绑定中进行评估。当然,它返回nil
。
要强制以常规方式评估块(即使用绑定到调用者的变量),您需要通过向其传递参数使block.arity.zero?
求值为false
。
Event.where.has{|event| (event.status == 'active') & (event.bot_client_id == @bot_client_id)}
答案 1 :(得分:0)
据我所知,has {}
方法是一个闭包,它改变了红宝石self
范围。你可以通过以下命令看到它:
p self
Event.where.has{ p self; (status == 'active') & (bot_client_id == @bot_client_id) }
如果输出不同,则表示第二次执行中的@bot_client_id
返回nil。