0

给定这样的示例模型:

class Foo < ActiveRecord::Base
  belongs_to :bar
end

class Bar < ActiveRecord::Base
  has_many :foos
  belongs_to :baz
end

class Baz < ActiveRecord::Base
  has_many :bars
  belongs_to :qux
end

class Qux < ActiveRecord::Base
  resourcify
  has_many :bazzes
end

以下代码按预期工作:

records = Foo.joins(bar: { baz: :qux }).merge(Qux.where(x: 17))

然而

records = Foo.joins(bar: { baz: :qux }).merge(Qux.with_role(:admin))

返回Foo已使用表中的值填充的记录集合quxxes。这意味着例如records.zwhere zis a column on foosbut not onquxxes将给出缺少属性的错误。您几乎可以通过以下方式解决此问题:

records = Foo.select('foos.*').joins(bar: { baz: :qux }).merge(Qux.with_role(:admin))

但这是具有欺骗性的,因为它会从列中获取值,而不是quxxesfoos具有相同名称的列中获取值,例如id, created_at,并且updated_at在典型的 Rails 应用程序中将来自quxxes

4

1 回答 1

0

所以问题原来是 rolify 向关系添加了一个选择(在这个适配器with_role的第 23 行)。

在研究了如何ActiveRecord存储 select 语句(参见该文件的第 249 和 69 行)之后,我们提出了以下解决方案:

records = Foo.joins(bar: { baz: :qux }).merge(Qux.with_role(:admin)).tap { |rel| rel.select_values = ['foos.*'] }

这将删除合并添加的选择并将其替换为我们自己的。或者,我们也可以将 select 移到调用链的末尾,这似乎也可以:

records = Foo.joins(bar: { baz: :qux }).merge(Qux.with_role(:admin)).select('foos.*')
于 2014-11-07T20:38:29.223 回答