ActiveRecord Joins获取子对象而不是父对象

时间:2014-11-07 17:37:07

标签: ruby-on-rails ruby join activerecord ruby-on-rails-4

我的问题:

我有三种模式:公司,父母和子女。

belongs_to公司

的孩子belongs_to家长

我需要让所有孩子在一家公司内将某个属性设置为false。 (Parent模型有一个company_id而Child模型没有。)

我在尝试什么:

我有以下加入:

@objects = Parent.joins(:childs).where('parents.company_id' => current_user.company_id, 'childs.foo' => false)

在我看来:

<!-- This should be a list of child objects -->
<% @objects.each do |obj| %>
<%= obj.foo %>
<% end %>

(foo是子对象的属性)

型号:

class Company < ActiveRecord::Base
  has_many :parents, :dependent => :destroy
  ...
end


class Parent < ActiveRecord::Base
  has_many :childs, :dependent => :destroy
  belongs_to :company
  ...
end


class Child < ActiveRecord::Base
  belongs_to :parent
  ...
end

但是,编写Parent.joins(:childs)...会返回Parent对象的ActiveRecord关系。 (当我尝试访问子属性时抛出错误)我需要结束列表是子对象。但我发现很难这样做。

这个问题的一个好答案是:

  • 以另一种更有意义的方式解决了这个问题,而不是计算量过大。

  • 或显示如何获取子对象的列表/关系而不是父对象的内容。

1 个答案:

答案 0 :(得分:9)

简单,从Child类开始:

Child.joins(:parent).where(parents: {company_id: current_user.company_id}, foo: false)

我可能会建议使用范围/类方法以更清洁的方式实现这一目标:

class Parent < ActiveRecord::Base
  def self.for_user(user)
    where(company_id: user.company_id)
  end
end

class Child < ActiveRecord::Base
  scope :fooless, ->{where foo: false}
end

现在你可以这样做:

Child.joins(:parent).merge(Parent.for_user(current_user)).fooless