【问题标题】:How to use ActiveRecord in deep association如何在深度关联中使用 ActiveRecord
【发布时间】:2012-05-05 03:24:34
【问题描述】:

我想通过以下模型中的 bar 获取与单个 foo 关联的 Bar 记录, Foo <-> Bar <-> Baz.

class Foo < ActiveRecord::Base
  has_many :foo_bar_assocs
  has_many :bars, through: :foo_bar_assocs
end

class Bar < ActiveRecord::Base
  has_many :bar_baz_assocs
  has_many :bazs, through: :bar_baz_assocs
  attr_readonly :name
end

class Baz < ActiveRecord::Base
end

class FooBarAssoc < ActiveRecord::Base
  belongs_to :foo
  belongs_to :bar
end

class BarBazAssoc < ActiveRecord::Base
  belongs_to :bar
  belongs_to :baz
end

天真的实现:

foo = Foo.find(id)
baz_of_foo = foo.bars.where(name: params[:name]).map{|b| b.bazs}.flatten.uniq

这段代码生成了错误的查询,它执行了很多次。 我想要的是如下内容:

baz_of_foo = foo.something_good_query(bar_name: params[:name])

另外,我想获取像 ActiveRecord::Relation 这样的对象,以便优化生成的 SQL 查询。

baz_of_foo.each{ ... } # SELECT DISTINCT baz.* FROM ...
baz_of_foo.count       # SELECT COUNT(DISTINCT baz.*) FROM ...
baz_of_foo.exists?     # SELECT baz.* FROM ... TAKE 1

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    你也应该定义反向关系,一旦你完成了,你应该能够做这样的事情:

    Baz.joins(:bar => :foo).where(:bar => {:name => params[:name], :foo => {:id => foo_id}})
    

    对于复杂的查询,我还推荐squeel gem,它允许更紧凑的查询并且还支持外连接。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-13
      • 1970-01-01
      相关资源
      最近更新 更多