Ruby 使用字符串或实例变量时,ActiveRecord查询不同

Ruby 使用字符串或实例变量时,ActiveRecord查询不同,ruby,activerecord,Ruby,Activerecord,如果查看查询,@bot\u client\u id是一个与string值相同的字符串。但是,当将它们用作查询的一部分时,我会得到不同的结果 为什么? [24]撬动(#):1>字符串 =>“aiaas-1409611358153-user-0149” [25]撬动(#):1>@bot#u客户端\u id =>“aiaas-1409611358153-user-0149” [26]pry(#):1>事件。where.has{(status=='active')&(bot\u client\u id=

如果查看查询,
@bot\u client\u id
是一个与
string
值相同的字符串。但是,当将它们用作查询的一部分时,我会得到不同的结果

为什么?

[24]撬动(#):1>字符串
=>“aiaas-1409611358153-user-0149”
[25]撬动(#):1>@bot#u客户端\u id
=>“aiaas-1409611358153-user-0149”
[26]pry(#):1>事件。where.has{(status=='active')&(bot\u client\u id==@bot\u client\u id)}
=> []
[27]pry(#):1>事件。其中.has{(status='active')&(bot_client_id==string)}
=> [#,
#]

据我所知,
有{}
方法是一个闭包,它改变了rubies
自身的范围。您可以通过以下命令查看它:

p self
Event.where.has{ p self; (status == 'active') & (bot_client_id == @bot_client_id) }

如果输出不同,则第二次执行中的
@bot\u client\u id
返回nil

据我所知,
has{}
方法是一个闭包,它改变了rubies
self
的范围。您可以通过以下命令查看它:

p self
Event.where.has{ p self; (status == 'active') & (bot_client_id == @bot_client_id) }
如果输出不同,则第二次执行中的
@bot\u client\u id
返回nil

查看您的代码:

Event.where.has{(status == 'active') & (bot_client_id == @bot_client_id)}
has
获取一个块,其中调用了
status
bot\u client\u 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>'
看起来传递到块中的变量只有在处理块时才进行计算(通常使用
yield
block.call
)。看起来这个块不是按正常方式处理的

通过谷歌搜索可以发现,
.where.has{}
是属于 . Babysquel文件规定:

Babysquel的块使用instance_eval,这意味着您将无法访问实例变量或方法

在中,相关的方法似乎是
evaluate

@bot\u client\u id
在接收方绑定(这是一个
babysquel::DSL
对象)而不是调用方绑定中进行计算。当然,它返回
nil

要强制以通常的方式对块求值(即使用绑定到调用方的变量),需要通过向其传递参数使
block.arity.zero?
求值为
false

Event.where.has{|event| (event.status == 'active') & (event.bot_client_id == @bot_client_id)}
查看您的代码:

Event.where.has{(status == 'active') & (bot_client_id == @bot_client_id)}
has
获取一个块,其中调用了
status
bot\u client\u 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>'
看起来传递到块中的变量只有在处理块时才进行计算(通常使用
yield
block.call
)。看起来这个块不是按正常方式处理的

通过谷歌搜索可以发现,
.where.has{}
是属于 . Babysquel文件规定:

Babysquel的块使用instance_eval,这意味着您将无法访问实例变量或方法

在中,相关的方法似乎是
evaluate

@bot\u client\u id
在接收方绑定(这是一个
babysquel::DSL
对象)而不是调用方绑定中进行计算。当然,它返回
nil

要强制以通常的方式对块求值(即使用绑定到调用方的变量),需要通过向其传递参数使
block.arity.zero?
求值为
false

Event.where.has{|event| (event.status == 'active') & (event.bot_client_id == @bot_client_id)}

@bot\u client\u id.class
返回什么?我之所以这样问,是因为
@bot\u client\u id
在控制台中返回一个字符串,但这并不一定意味着它是一个字符串。它的
inspect
to\u s
方法可能会被覆盖。这是什么
。有
方法吗?它是来自activerecord还是其他库?它返回一个string类。也检查了..has是从婴儿挤压机返回的
@bot\u client\u id.class
返回什么?我之所以这样问,是因为
@bot\u client\u id
在控制台中返回一个字符串,但这并不一定意味着它是一个字符串。它的
inspect
to\u s
方法可能会被覆盖。这是什么
。有
方法吗?它是来自activerecord还是其他库?它返回一个string类。也检查过了…是婴儿奶昔杰玛的,我想你知道了。描述得很好。谢谢。啊,我想你明白了。描述得很好。非常感谢。