根据更深层关联的计数过滤嵌套关联的结果

时间:2014-06-14 22:34:22

标签: ruby-on-rails rails-activerecord active-record-query

我有以下模特和协会:

class ClassProfile < ActiveRecord::Base

  has_many :enrollments, dependent: :destroy
  has_many :student_profiles, through: :enrollments

class Enrollment < ActiveRecord::Base

  belongs_to :student_profile
  belongs_to :class_profile

class StudentProfile < ActiveRecord::Base

  has_one :enrollment, dependent: :destroy
  has_one :class_profile, through: :enrollment
  has_many :relationships
  has_many :parent_profiles, through: :relationships

class Relationship < ActiveRecord::Base

  belongs_to :student_profile
  belongs_to :parent_profile

class ParentProfile < ActiveRecord::Base

  has_many :relationships
  has_many :student_profiles, through: :relationships

我想要做的是为ClassProfile

定义类似下面的方法
class ClassProfile < ActiveRecord::Base
  ...
  def orphans
    #return a collection of all student_profiles where
    #there are no parent_profiles associated
    #(i.e. parent_profiles.count = 0 or parent_profiles.empty? = true
  end

如果可能,我想用单个语句执行此操作,我不必编写一个手动查询每个student_profile的循环。有没有办法做到这一点,如果有,那是什么?

更新 澄清一下:我在StudentProfile中有一个方法,如下所示:

class StudentProfile < ActiveRecord::Base

  def child?
    self.relationships[0].present?
  end

所以我想使用这样的方法:

class ClassProfile < ActiveRecord::Base
  ...
  def orphans
    self.student_profiles.where( child? == false )
  end

即,返回正确集合的单个语句。但这不是where的有效用法并且会引发错误。这是有道理的,因为据我所知,关联模型上的where方法仅适用于字段,而不适用于方法。无论如何,这是我正在寻找的东西,只有实际上有效的东西。

2 个答案:

答案 0 :(得分:0)

也许你可以为此加入。在ClassProfile

    def orphans
      self.joins(student_profiles: :relationships)
    end

此处的连接是内连接。没有关系的学生将不会加入这里。此外,也许你可以为你的方法尝试一个更好的名字。你的命名很模糊。

答案 1 :(得分:0)

我想出来了。这是具有所需行为的代码:

  def orphans
    student_profiles.reject { |s| s.child? }
  end

我认为这需要遍历所有学生档案(而不是在查询级别工作),但它可以完成工作。