我正在使用ancestry gem来构建树中的某些组。与此同时,我正在使用acts_as_list将组保持在排序列表中的同一树级别。鉴于以下模型:
class Group < ActiveRecord::Base
acts_as_tree
acts_as_list :scope => "ancestry"
named_scope :parentable, :conditions => "NOT type = 'PriceGroup'"
named_scope :without, lambda { |ids| { :conditions => ['id NOT IN (?)', ids] }}
default_scope :order => "groups.position ASC, groups.name ASC"
end
这非常符合预期,例如我使用@group.path
在管理界面的顶部生成面包屑导航。生成的SQL没问题,面包屑按树深度排序。至少在开发环境中也是如此。
在生产中它看起来完全不同:跟踪生成的SQL我发现不是祖先的path
生成结果顺序,而是我的default_scope
接管。
所以我修改了我的模型,通过覆盖path
来忽略默认范围:
# remove default scope to not change path sorting
def path
self.class.send :with_exclusive_scope do
super
end
end
但是虽然这在开发中删除了我default_scope
的位置范围,但在生产中仍然完全被忽略。在生产中跟踪SQL,我没有看到祖先的深度排序,而是从default_scope
看到位置排序。
更新:由于我最初的“修补”path
方法的想法有些愚蠢(敲敲:它不是继承的,它是动态定义的),我尝试了以下仍然没有果:
# remove default scope to not change path sorting
def path_with_exclusive_scope
self.class.send :with_exclusive_scope do
path_without_exclusive_scope
end
end
alias_method_chain :path, :exclusive_scope
在开发中调用path
时,生成的SQL如下:
SELECT *
FROM "groups"
WHERE ("groups"."id" IN (5,64))
ORDER BY (case when ancestry is null then 0 else 1 end), ancestry
与此相比,生产中生成的SQL:
SELECT *
FROM `groups`
WHERE (`groups`.`id` IN (8,49))
ORDER BY groups.position ASC, groups.name ASC
开发使用SQLite,其中生产使用MySQL - 但我不认为这是至关重要的区别。
答案 0 :(得分:1)
acts_as_list
在处理default_scope时有一些bugs。你应该避免使用它或在GitHub上寻找固定版本。试试this version(您可以在我之前链接的拉取请求中找到相关提交的链接)
答案 1 :(得分:0)
我使用范围方法遇到了类似的问题,我在祖先维基上找到了这个问题。
has_ancestry :cache_depth =>true
acts_as_list :scope => 'ancestry = \'#{ancestry}\''
named_scope :ordered, :order => "ancestry_depth,position DESC"
https://github.com/stefankroes/ancestry/wiki/arrange_as_array