1

我有两个具有 1:N 关系的不同模型。让我们将它们命名为“myobject”和“related”

class Myobject < ActiveRecord::Base
  has_many :related
  scope :without_related, includes(:related).select{ |o| o.related.size == 0 }
end
class Related < ActiveRecord::Base
end

只要我不创建从 Myobjects 到相关的新分配,定义的范围似乎工作得很好:

  • 直接 rails c command "Myobject.includes(:related).select ...(在 Scope 中定义)按预期工作
  • 对范围“Myobject.without_related”的调用仍然返回同时已分配的对象

似乎可以通过重新启动 rails 控制台或重新启动 Webrick 来解决此问题。但是我不能总是因为对象之间的关系已经改变而重新启动 web 应用程序;)

有没有办法解决这个问题或以更好的方式编写范围?

PS:我需要这个查询作为范围以将其名称作为 group_method 以 Myobject 模型的形式传递给 grouped_select

4

3 回答 3

3

您的问题是,实际上您的范围不是范围:)

范围必须返回关系,但您的范围返回数组。

尽管它可以按您的预期工作,但如果您将其包装在 lambda 中

 scope :without_related, lambda{ includes(:related).select{ |o| o.related.size == 0 } }

但我建议将此代码重写为通常的类方法,以免误导将来使用此代码的人

def self.without_related
  includes(:related).select{ |o| o.related.size == 0 }
end

或按照其他答案中的建议使用计数器缓存。

于 2012-12-18T17:50:42.683 回答
0

我建议您为此使用 counter_cache,您需要将 int 类型的列 *related_count* 添加到 Myobject,进行迁移,然后您将能够这样做:

class Myobject < ActiveRecord::Base
  has_many :related
  scope :without_related, where(related_count: 0)
end

class Related < ActiveRecord::Base
  belongs_to :myobject, counter_cache: true
end

之后,您将拥有超快的范围来获取没有相关记录的所有对象以及该对象的计数

于 2012-12-18T17:46:54.427 回答
0

或者,如果您知道相关表中应该存在的列名,请使用以下定义:

class Myobject < ActiveRecord::Base
  has_many :related
  scope :without_related, includes(:related).where('related.id', true)
end
于 2012-12-18T17:56:49.553 回答