Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.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 on rails 如何从现有ActiveRecord_关系中获取where表达式中使用的列?_Ruby On Rails_Reflection_Rails Activerecord_Arel - Fatal编程技术网

Ruby on rails 如何从现有ActiveRecord_关系中获取where表达式中使用的列?

Ruby on rails 如何从现有ActiveRecord_关系中获取where表达式中使用的列?,ruby-on-rails,reflection,rails-activerecord,arel,Ruby On Rails,Reflection,Rails Activerecord,Arel,假设我的很多模型实现了一个类方法self.foo,它返回一个::ActiveRecord\u关系 从代码的其他地方,我可以访问该方法返回的模型或::ActiveRecord_关系,我想知道查询中的where表达式中使用了哪些列 如果查询很简单,我可以从ActiveRecord\u关系的where\u values\u hash获取它,但是我很难弄清楚如何在更复杂的查询中获取所有列 class A < ApplicationRecord def self.foo(bar) whe

假设我的很多模型实现了一个类方法self.foo,它返回一个::ActiveRecord\u关系

从代码的其他地方,我可以访问该方法返回的模型或::ActiveRecord_关系,我想知道查询中的where表达式中使用了哪些列

如果查询很简单,我可以从ActiveRecord\u关系的where\u values\u hash获取它,但是我很难弄清楚如何在更复杂的查询中获取所有列

class A < ApplicationRecord
  def self.foo(bar)
    where(column1: bar)
  end
end

class B < ApplicationRecord
  def self.foo(bar)
    joins(:c).
    merge(C.where(column2: bar))
  end
end

我总是可以通过解析关系的.to\u sql字符串来获得它,但必须有更好的方法。

where\u values\u散列方法使用一个参数,该参数是您希望where子句列来自的表。如果你想要所有的表,你可以用Arel做一些事情来得到所有的连接表。唯一的技巧是,您可能希望保留列来自的表的上下文

def join_where_values(relation)
  relation.arel.join_sources.map do |r|
    { r.left.name => relation.where_values_hash(r.left.name) }
  end
end

{ 'b' => B.foo(bar).where_values_hash, 'joins' => join_where_values(B.foo(bar)) }
def join_where_values(relation)
  relation.arel.join_sources.map do |r|
    { r.left.name => relation.where_values_hash(r.left.name) }
  end
end

{ 'b' => B.foo(bar).where_values_hash, 'joins' => join_where_values(B.foo(bar)) }