【问题标题】:Use scope of a belongs_to association to scope in the first model - Ruby on Rails在第一个模型中使用 belongs_to 关联的范围 - Ruby on Rails
【发布时间】:2017-03-28 09:24:03
【问题描述】:

问题

假设我有两个具有 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

我想在子模型上创建一个范围,它使用父模型的范围。

有什么办法让我可以在 Parent 上使用范围的定义吗?

当前解决方案

我现在的做法是

class Child < ApplicationRecord
  belongs_to :parent
  scope :wit_great_parent, -> (min_grade) {
        join(:parent).where("grade > :grade", grade: min_grade)}
end

但是,我在两个地方都复制了 where 子句。

问题

是否可以从子模型中调用 Parent 范围?

【问题讨论】:

  • 孩子只有一个父母,所以我认为限定单个对象没有多大意义:/也许return nil if parent.grade &gt; min_grade
  • 我想返回所有有更高成绩的父母的孩子。我不想让所有的孩子都按照你提出的“如果”一一检查。

标签: ruby-on-rails ruby ruby-on-rails-5 rails-activerecord


【解决方案1】:

如果你只是想在范围内合并,那么

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

【讨论】:

  • 是的!而已!谢谢
【解决方案2】:

嗯,也许,您只需将 parents. 放在 Child 范围内的 grade &gt; :grade 查询之前。你拼错了joins 方法。

尝试像这样在子模型上使用范围:

class Child < ApplicationRecord
  belongs_to :parent
  scope :wit_great_parent, -> (min_grade) {
        joins(:parent).where("parents.grade > :grade", grade: min_grade)
  }
end

【讨论】:

    猜你喜欢
    • 2013-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-21
    相关资源
    最近更新 更多