我有一个属于Category的Entry模型。Category模型使用祖先,这样我就可以嵌套Categories。
我想按根类别对所选条目进行分组。我遇到的问题是,为了做到这一点,rails对每个条目执行一个查询,以获取根类别。因此,如果我有20条记录,它将执行20个查询,按根类别进行分组。
我已经通过急切地加载类别(如下所示)减少了查询的数量,但我也不知道如何急切地加载该类别的根。
这是我正在使用的代码:
控制器
@entries = current_user.entries.includes(:category)
@entries_by_category = @entries.group_by { |entry| entry.category.root }
entry.rb
class Entry < ActiveRecord::Base
belongs_to :category
end
类别.rb
class Category < ActiveRecord::Base
has_ancestry
has_many :entries
end
我尝试在Category模型上设置一个默认作用域,如下所示:default_scope { includes(:ancestry) }
。但这并没有改变已执行查询的数量。我不知道如何在原始查询中使用includes()
来同时包含类别和类别的根。
作为一点额外信息,类别只能嵌套2层(只有类别和子类别)。所以根在技术上意味着父,它不必遍历多个级别。
有什么想法吗?
我遇到了一个非常类似的问题,只是我想急切地加载类别的path
,而不仅仅是root
。不幸的是,急切加载只适用于关联。Ancestry导航器(parent
、root
、path
、ancestors
等)都是方法,而不是关联,因此您不能急于加载它们。
我的解决方案是急切地加载条目的类别关联,然后在Category
上使用模型级缓存(请参阅Railscast#115)来缓存path
(在您的情况下,您可以修改为root
):
类别.rb
def cached_path
Rails.cache.fetch([self, "path"]) { path.to_a }
end
entries_controller.rb
def index
@entries = Entry.includes(:category)
end
views/entries/index.html.haml
- @entries.each do |entry|
= entry.category.cached_path.map{ |c| c.name }.join(" / ")
希望能有所帮助。