Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

AR 3.0.5 / 3.0.7 + default_scope(order('blah')) + #arrange method are incompatible #42

Closed
jbbarth opened this Issue · 3 comments

4 participants

@jbbarth

When you have a "default_order" directive in your AR class with AR 3.0.5 or 3.0.7, #arrange method doesn't work properly. Everything runs fine with AR 3.0.0.

I wrote a little test if you want to see the issue :

  def test_arrangement_nesting
    AncestryTestDatabase.with_model :extra_columns => {:name => :string} do |model|
      model.send :default_scope, model.order('name')
      node2 = model.create! :name => 'Linux'
      node1 = model.create! :name => 'Debian'
      node1.parent = node2
      node1.save
      #expected: {Linux => Debian}
      #got: {Debian, Linux}
      assert_equal 1, model.arrange.count
    end
  end

To run it:

% ar=3.0.7 ruby -Ilib test/has_ancestry_test.rb -n test_arrangement_nesting
#=> KO
#=>
#  1) Failure:
# test_arrangement_nesting(HasAncestryTreeTest) [test/has_ancestry_test.rb:440]:
# <1> expected but was
# <2>.

% ar=3.0.0 ruby -Ilib test/has_ancestry_test.rb -n test_arrangement_nesting
#=> OK

I suppose it can be a problem in the OrderedHash class or in Arel, so maybe not directly related to AR, I'll have a deeper look at it, but any idea is welcome...

@stefankroes
Owner

having

model.send :default_scope, model.order('name')

breaks about half of all tests, also on rails 3.0, I don't understand why though: the testing models should be totally isolated

@petehamilton

I just experienced this as well, any further ideas?

Mine was when updating the ancestry property of several models and then asking for them to be arranged.

Here is a brief example and some information which might help.

Category Model (object I am nesting)

  default_scope :order => 'name ASC'

Then I have a function which prints a tree to the terminal.

  def printTerminalTreeForHash(categories, level = 0)
    categories.each do |c, cs|
      puts "   "*level + "|- #{c.name}, #{c.id}, #{c.ancestry},"
      if !cs.empty?
        printTerminalTreeForHash cs, level + 1
      end
    end
    return ""
  end

Which produces this style: |- name, id, ancestry

|- Root, 5, ,
   |- C1, 6, 5,
      |- C1.1, 7, 5/6,
         |- C1.1.1, 8, 5/6/7,
      |- C1.2, 10, 5/6,
         |- C1.1.2, 9, 5/6/10,
         |- C1.2.1, 11, 5/6/10,
         |- C1.2.2, 12, 5/6/10,

Somewhere I have code akin to the following:

printTerminalTreeForHash(@category.descendants.arrange)
@category.descendants.map{|c| "#{c.id}: #{c.ancestry}"}.inspect
puts @category.descendants.
#Update with the new ancestry (e.g. 1/2 => 1/2/3 if moved into subfolder)
@category.descendants.each {|c| c.update_attributes(ancestry: c.ancestry.gsub(old_ancestry, @category.ancestry))}
printTerminalTreeForHash(@category.descendants.arrange)

And I somehow end up with the following tree in my terminal:

|- C1, 6, 5,
   |- C1.1, 7, 5/6,
      |- C1.1.1, 8, 5/6/7,
   |- C1.1.2, 9, 5/6/10,
   |- C1.2, 10, 5/6,
      |- C1.2.1, 11, 5/6/10,
      |- C1.2.2, 12, 5/6/10,
|- C2, 13, 5,
   |- C2.1, 14, 5/13,
      |- C2.1.1, 15, 5/13/14,
      |- C2.1.2, 16, 5/13/14,
   |- C2.2, 17, 5/13,
   |- C2.2.1, 18, 5/13/19,
   |- C2.2.2, 19, 5/13,
|- Root, 5, ,

As you can see, the ancestry updated fine, but for some reason it's not nesting/arranging correctly (See second node from the bottom).

If I remove the default scope on my categories it all works fine. WEIRD.

@StefanH
Collaborator

fixed in 2.0 by 8850dca. Arrange would break if there was a default scope with order. Arrange will now reorder to ignore the default scope, so it works but ignores the default scopes' ordering. To apply an order to arrange, use arrange(order: 'name ASC'). See also: #124

@StefanH StefanH closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.