5

我有一个属于类别的条目模型。类别模型使用祖先,以便我可以嵌套类别。

我想按它们的根类别对一组条目进行分组。我遇到的问题是,为了做到这一点,rails 对每个条目执行查询以获取根类别。因此,如果我有 20 条记录,它将执行 20 个查询以按根类别分组。

我已经通过预先加载类别(如下所示)减少了查询数量,但我不知道如何预先加载类别的根。

这是我正在使用的代码:

控制器

@entries = current_user.entries.includes(:category)
@entries_by_category = @entries.group_by { |entry| entry.category.root }

入口.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 级深度(只是类别和子类别)。所以根技术上意味着父级,它不必遍历多个级别。

有任何想法吗?

4

1 回答 1

4

我有一个非常相似的问题,除了我想急切加载类别path而不仅仅是root. 不幸的是,急切加载仅适用于关联。Ancestry 导航器(parentrootpathancestors等)都是方法,而不是关联,因此您不能急切地加载它们。

我的解决方案是急切加载条目的类别关联,然后使用模型级缓存(参见Railscast #115Category来缓存path(您可以根据root您的情况修改):

类别.rb

def cached_path
  Rails.cache.fetch([self, "path"]) { path.to_a }
end

entry_controller.rb

def index
  @entries = Entry.includes(:category)
end

视图/条目/index.html.haml

- @entries.each do |entry|
  = entry.category.cached_path.map{ |c| c.name }.join(" / ")

希望有帮助。

于 2014-06-01T15:57:17.727 回答