Mixing act_as_tree (pedigree gem), act_as_list and model model

I use a pedigree to structure some groups in a tree. At the same time, I use act_as_list to save groups on the same tree level in a sorted list. Given the following model:

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 

This worked pretty much as intended, for example, I use @group.path to create navigation at the top of the admin interface. The generated SQL is fine, breadcrumbs are sorted by tree depth as needed. At least this is true for the development environment.

In production, this looks completely different: I found that the generated SQL trace did not ancestry path generate the order of the result, but default_scope takes over.

So, I fixed my model to ignore the default scope by overwriting path :

 # remove default scope to not change path sorting def path self.class.send :with_exclusive_scope do super end end 

But while this removed the position definition from my default_scope in development, it is still completely ignored during production. Tracking SQL during production, I don’t see the depth order of the ancestors, but instead it arranges the positions from my default_scope .

Update: Since my original idea of β€‹β€‹β€œfixing” the path method was somewhat stupid (detonation act: it is not inherited, it is dynamically determined), I tried the following to no avail:

 # 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 

When calling path in development, the generated SQL looks like this:

 SELECT * FROM "groups" WHERE ("groups"."id" IN (5,64)) ORDER BY (case when ancestry is null then 0 else 1 end), ancestry 

Compared to this, the generated SQL in production is here:

 SELECT * FROM `groups` WHERE (`groups`.`id` IN (8,49)) ORDER BY groups.position ASC, groups.name ASC 

SQLite is used in development, where products use MySQL, but I don’t think this is the key difference here.

+4
source share
2 answers

acts_as_list contains errors while processing default_scope. You should either not use it or look for a fixed version on GitHub. Try this version (you can find a link to the corresponding commit in the transfer request that I linked earlier)

+1
source

I had a similar problem using the scope method, I found this on the wiki pedigree.

  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

0
source

Source: https://habr.com/ru/post/1303399/


All Articles