Rails 4 has_and_belongs_to_many specific order

111 views
Skip to first unread message

Henrique Vilela

unread,
May 14, 2014, 2:13:51 PM5/14/14
to rubyonra...@googlegroups.com

I'm trying to set a specific order to an association, but I keep getting the default scope order definition.

What am I missing?


class Pattern < ActiveRecord::Base

  default_scope { order('sort, title') }

  has_and_belongs_to_many :children,

    :class_name => 'Pattern'

    :join_table => 'patterns_patterns',

    :association_foreign_key => 'child_id',

    :foreign_key => 'parent_id',

    :order => 'patterns_patterns.updated_at'

end


SELECT "patterns".* FROM "patterns" INNER JOIN "patterns_patterns" ON "patterns"."id" = "patterns_patterns"."child_id" WHERE "patterns_patterns"."parent_id" = ?  ORDER BY sort, title  [["parent_id", 1]]

Colin Law

unread,
May 15, 2014, 4:34:26 AM5/15/14
to rubyonra...@googlegroups.com
On 14 May 2014 19:13, Henrique Vilela <henriqu...@gmail.com> wrote:
> I'm trying to set a specific order to an association, but I keep getting the
> default scope order definition.
>
> What am I missing?

I tend to avoid default_scope for exactly this reason, the results are
not always obvious. I prefer to use named scopes or specify the order
explicitly. Then you have better control of what is going on. Many
believe default scopes are evil. I believe you can override it using
reorder.

Colin

Matt Jones

unread,
May 15, 2014, 9:11:01 AM5/15/14
to rubyonra...@googlegroups.com
Which Rails version are you running? There were a substantial number of  issues with default_scope fixed in 4.0 and 4.1.

--Matt Jones

Henrique Vilela

unread,
May 15, 2014, 9:56:11 AM5/15/14
to rubyonra...@googlegroups.com
Hi Colin, thank you for your answer.
I just realized that my problem is bigger than that. I removed the default_scope and my query now is "orderbyless".

SELECT "patterns".* FROM "patterns" INNER JOIN "patterns_patterns" ON "patterns"."id" = "patterns_patterns"."child_id" WHERE "patterns_patterns"."parent_id" = ?  [["parent_id", 7]]


Why the order is been ignored?

class Pattern ActiveRecord::Base

  has_and_belongs_to_many :children,

    :class_name => 'Pattern'

    :join_table => 'patterns_patterns',

    :association_foreign_key => 'child_id',

    :foreign_key => 'parent_id',

    :order => 'patterns_patterns.updated_at'

end

Henrique Vilela

unread,
May 15, 2014, 9:57:49 AM5/15/14
to rubyonra...@googlegroups.com
Hi Matt,

My Rails version is 4.1.0.

Matt Jones

unread,
May 16, 2014, 8:27:18 AM5/16/14
to rubyonra...@googlegroups.com


On Thursday, 15 May 2014 09:56:11 UTC-4, Henrique Vilela wrote:
Hi Colin, thank you for your answer.
I just realized that my problem is bigger than that. I removed the default_scope and my query now is "orderbyless".

SELECT "patterns".* FROM "patterns" INNER JOIN "patterns_patterns" ON "patterns"."id" = "patterns_patterns"."child_id" WHERE "patterns_patterns"."parent_id" = ?  [["parent_id", 7]]


Why the order is been ignored?

class Pattern ActiveRecord::Base

  has_and_belongs_to_many :children,

    :class_name => 'Pattern'

    :join_table => 'patterns_patterns',

    :association_foreign_key => 'child_id',

    :foreign_key => 'parent_id',

    :order => 'patterns_patterns.updated_at'

end



The `order` option was removed a while back - things that change the query should be done in a scope lambda instead:

has_and_belongs_to_many :children, -> { order(:something) }, ...

--Matt Jones

Henrique Vilela

unread,
May 16, 2014, 6:38:15 PM5/16/14
to rubyonra...@googlegroups.com
Thank you Matt,

It kind for work. It added a new order item instead of replace it.

class Pattern < ActiveRecord::Base

  default_scope { order('sort, title') }


  has_and_belongs_to_many :children,

    -> { order('patterns_patterns.id') },

    :class_name => 'Pattern'

    :join_table => 'patterns_patterns',

    :association_foreign_key => 'child_id',

    :foreign_key => 'parent_id'


end


... ORDER BY sort, title, patterns_patterns.id 


Any idea?

Henrique Vilela

unread,
May 16, 2014, 8:41:04 PM5/16/14
to rubyonra...@googlegroups.com
Solved.

If anybody is having the same issue, the answer is to use "reorder" instead of order.

Thank you all.

Colin Law

unread,
May 17, 2014, 11:34:09 AM5/17/14
to rubyonra...@googlegroups.com
On 17 May 2014 01:41, Henrique Vilela <henriqu...@gmail.com> wrote:
> Solved.
>
> If anybody is having the same issue, the answer is to use "reorder" instead
> of order.

I think that is what I said in my first reply.

Colin
Reply all
Reply to author
Forward
0 new messages