Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 在动态条件下使用lambda_Ruby_Ruby On Rails 3_Associations_Conditional Statements - Fatal编程技术网

Ruby 在动态条件下使用lambda

Ruby 在动态条件下使用lambda,ruby,ruby-on-rails-3,associations,conditional-statements,Ruby,Ruby On Rails 3,Associations,Conditional Statements,我定义了一个与这样的动态条件有很多关联的函数: class Checkin < ActiveRecord::Base has_many :evaluations, :conditions => proc {"evaluations.placement_id = #{self.placement_id}"} end 由于我更喜欢lambdas而不是procs,因此我尝试用lambda替换关联条件,但此尝试会导致错误: :conditions => lambda {"eval

我定义了一个与这样的动态条件有很多关联的函数:

class Checkin < ActiveRecord::Base
  has_many :evaluations, :conditions => proc {"evaluations.placement_id = #{self.placement_id}"}
end
由于我更喜欢lambdas而不是procs,因此我尝试用lambda替换关联条件,但此尝试会导致错误:

:conditions => lambda {"evaluations.placement_id = #{self.placement_id}"}

> Checkin.find(1).evaluations.to_sql
ArgumentError: wrong number of arguments (1 for 0)
通过向lambda块提供参数,可以轻松修复该错误:

:conditions => lambda {|a| "evaluations.placement_id = #{self.placement_id}"}

> Checkin.find(1).evaluations.to_sql # a is nil inside of this lambda call!
=> "SELECT \"evaluations\".* FROM \"evaluations\"  WHERE \"evaluations\".\"checkin_id\" = 1 AND (evaluations.placement_id = 2)"
传递参数没有区别,lambda的参数始终为零:

:conditions => lambda {|a| puts "a: #{a || 'undefined'}"; "evaluations.placement_id = #{self.placement_id}"}

Checkin.find(1).evaluations(5) # => has no effect on produced sql
a: undefined
# and here are returned evaluations
  • lambda块所需的参数是什么
  • 为什么会在那里
  • 为什么该参数总是保持为零

  • 这种行为是由于
    ActiveRecord::Associations::Association#interpolate
    ,当Rails根据条件确定关联范围时调用该函数。这个电话看起来像:

    scope = scope.where(interpolate(condition))
    
    以下是
    interpolate
    方法的全文(来自3.2源代码:):

    在该方法中,
    sql
    是lambda条件,
    owner
    计算为
    Checkin
    实例

    lambda响应
    到_proc
    ,因此满足
    条件。所以真正发生的事情是这样的:

    Checkin.find(1).instance_exec(nil) {"evaluations.placement_id ... "}
    

    这不起作用,因为
    nil
    是一个参数,所以块应该有一个参数(您已经知道lambdas检查算术)。如果执行
    lambda{a |…}
    a
    nil
    ,因为
    record
    nil
    (因为它的值没有传递给
    interpolate
    方法,而
    nil
    是默认值)。

    此行为是由于
    ActiveRecord::Associations::Association::Association
    ,当Rails确定与条件的关联范围时调用。这个电话看起来像:

    scope = scope.where(interpolate(condition))
    
    以下是
    interpolate
    方法的全文(来自3.2源代码:):

    在该方法中,
    sql
    是lambda条件,
    owner
    计算为
    Checkin
    实例

    lambda响应
    到_proc
    ,因此满足
    条件。所以真正发生的事情是这样的:

    Checkin.find(1).instance_exec(nil) {"evaluations.placement_id ... "}
    
    这不起作用,因为
    nil
    是一个参数,所以块应该有一个参数(您已经知道lambdas检查算术)。当您执行
    lambda{a |…}
    时,
    a
    nil
    ,因为
    record
    nil
    (因为它的值没有传递给
    interpolate
    方法,
    nil
    是默认值)