使用belongs_to关联的作用域来为第一个模型进行作用域限制 - Ruby on Rails

5

问题

假设我有两个模型,它们之间有一个 has_many-belongs_to 的关系。其中 has_many 定义了一个作用域和一个名为 grade 的整数属性。

class Parent < ApplicationRecord
  has_many :children
  scope :great, -> (min_grade) {where("grade > :grade", grade: min_grade)}
end

class Child < ApplicationRecord
  belongs_to :parent
end

我希望您能在子模型上创建一个作用域,该作用域使用父模型的作用域。是否有任何方法可以使用父级作用域的定义?

当前解决方案

目前我所做的方式是:
class Child < ApplicationRecord
  belongs_to :parent
  scope :wit_great_parent, -> (min_grade) {
        join(:parent).where("grade > :grade", grade: min_grade)}
end

然而,在这两个地方我都复制了where子句。

问题

有没有办法从子模型中调用父级作用域?


孩子只有一个父母,所以我认为将单个对象限定范围并没有太多意义 :/ 或许可以这样写:如果 parent.grade > min_grade,则返回 nil - gabrielhilal
我想返回所有父级成绩更高的子级。我不想通过您提出的“if”逐个获取所有子级并进行检查。 - Mateu
2个回答

7
如果您只是想在作用域中合并,则:
class Child < ApplicationRecord
  belongs_to :parent
  scope :with_great_parent, -> (min_grade) {joins(:parent).merge(Parent.great(min_grade))}
end

你应该处理这个问题。生成的SQL将类似于

SELECT * 
FROM children 
  INNER JOIN parents ON children.parent_id = parents.id
WHERE 
  parents.grade > --Whatever value you pass as min_grade

请查看ActiveRecord::SpawnMethods#merge了解更多信息。

是的!就是这样!谢谢 - Mateu

1
嗯,也许你只需要在Child的作用域中,在grade > :grade查询之前加上parents.。而且你拼错了joins方法。
尝试像这样在Child模型上使用作用域:
class Child < ApplicationRecord
  belongs_to :parent
  scope :wit_great_parent, -> (min_grade) {
        joins(:parent).where("parents.grade > :grade", grade: min_grade)
  }
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接