Note that there are some explanatory texts on larger screens.

plurals
  1. POMixing acts_as_tree (ancestry gem), acts_as_list and default model scoping
    primarykey
    data
    text
    <p>I'm using the <a href="http://github.com/stefankroes/ancestry" rel="nofollow noreferrer">ancestry gem</a> to structure some groups in a tree. At the same time I'm using acts_as_list to keep groups at the same tree level in a sorted list. Given the following model:</p> <pre><code>class Group &lt; ActiveRecord::Base acts_as_tree acts_as_list :scope =&gt; "ancestry" named_scope :parentable, :conditions =&gt; "NOT type = 'PriceGroup'" named_scope :without, lambda { |ids| { :conditions =&gt; ['id NOT IN (?)', ids] }} default_scope :order =&gt; "groups.position ASC, groups.name ASC" end </code></pre> <p>This worked pretty much as intended, eg I use <code>@group.path</code> to generate a breadcrumb navigation at the top of the admin interface. The generated SQL is okay, the breadcrumbs are sorted by tree depth as they should. At least this is true for the development environment.</p> <p>In production it looks completely different: Tracing the generated SQL I found that not ancestry's <code>path</code> is generating the result order but instead my <code>default_scope</code> takes over.</p> <p>So I fixed my model to ignore the default scope by overwriting <code>path</code>:</p> <pre><code># remove default scope to not change path sorting def path self.class.send :with_exclusive_scope do super end end </code></pre> <p>But while this removed the position scoping from my <code>default_scope</code> in development it still is completely ignored in production. Tracing the SQL in production, I don't see ancestry's depth ordering, but instead the position ordering from my <code>default_scope</code>.</p> <p><strong>Update:</strong> Since my original idea of "patching" the <code>path</code> method was somewhat silly (knock knock: it's not inherited, it's dynamically defined), I tried the following still to no avail:</p> <pre><code># 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 </code></pre> <p>When calling <code>path</code> in development the generated SQL is as follows:</p> <pre><code>SELECT * FROM "groups" WHERE ("groups"."id" IN (5,64)) ORDER BY (case when ancestry is null then 0 else 1 end), ancestry </code></pre> <p>Compared to that here's the generated SQL in production:</p> <pre><code>SELECT * FROM `groups` WHERE (`groups`.`id` IN (8,49)) ORDER BY groups.position ASC, groups.name ASC </code></pre> <p>Development uses SQLite where production uses MySQL - but I don't think that is the crucial difference here.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload