finding associations in sorted order

57 views
Skip to first unread message

Ronald Fischer

unread,
Jun 17, 2014, 8:35:05 AM6/17/14
to rubyonra...@googlegroups.com
I have in my model

class Card < ActiveRecord::Base
has_many :idioms, dependent: :destroy
end

class Idiom < ActiveRecord::Base
belongs_to :card
end

In my schema, Idiom has an integer column kind. Given a certain card, I
would like to have all associated idioms, but sorted in descending order
according to the 'kind' column.

I could do a

@card.idioms.sort { .... }

but would prefer doing the sorting by the time the data is retrieved
from the database. I googled two suggestions:

(1) @card.idioms(:order => 'kind DESC')

This doesn't seem to have any effect.

(2) @card.idioms.all(:order => 'kind DESC')

This gives the error "wrong number of arguments (1 for 0)".

I think I could do a

Idiom.where(....)

and put an order restriction there, but I feel that Rails must have a
way to specify sorting when following associations, and maybe I just
made some silly mistake. Any ideas?

--
Posted via http://www.ruby-forum.com/.

Walter Lee Davis

unread,
Jun 17, 2014, 8:44:18 AM6/17/14
to rubyonra...@googlegroups.com
It sounds to me as though maybe all of your idioms have the same value (or null) in their kind column. What does the database itself believe about these idioms? Have you tested that different values are being set for each? Also, what amount of data do you have?

Walter

>
> --
> Posted via http://www.ruby-forum.com/.
>
> --
> You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-ta...@googlegroups.com.
> To post to this group, send email to rubyonra...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/24d5871e8a39c5a3963122c9dffeeefc%40ruby-forum.com.
> For more options, visit https://groups.google.com/d/optout.

Colin Law

unread,
Jun 17, 2014, 9:00:14 AM6/17/14
to rubyonra...@googlegroups.com
On 17 June 2014 13:34, Ronald Fischer <li...@ruby-forum.com> wrote:
> I have in my model
>
> class Card < ActiveRecord::Base
> has_many :idioms, dependent: :destroy
> end
>
> class Idiom < ActiveRecord::Base
> belongs_to :card
> end
>
> In my schema, Idiom has an integer column kind. Given a certain card, I
> would like to have all associated idioms, but sorted in descending order
> according to the 'kind' column.
>
> I could do a
>
> @card.idioms.sort { .... }
>
> but would prefer doing the sorting by the time the data is retrieved
> from the database. I googled two suggestions:
>
> (1) @card.idioms(:order => 'kind DESC')
>
> This doesn't seem to have any effect.

What do you mean by not having any effect? It did not find anything,
or they were not sorted correctly?
If you have a look in log/development.log you will see the query being
run and check that it looks ok.

Colin

Ronald Fischer

unread,
Jun 17, 2014, 9:31:22 AM6/17/14
to rubyonra...@googlegroups.com
Walter Davis wrote in post #1149912:
> On Jun 17, 2014, at 8:34 AM, Ronald Fischer wrote:
> It sounds to me as though maybe all of your idioms have the same value
> (or null) in their kind column.

No, they have correct values (1, 2 and 3). Actually, the logic of the
application ensures that there are only those values (I should this
place into the model too).

Does it mean that in your opinion, my attempt to sort them would be
correct?


Ronald

Ronald Fischer

unread,
Jun 17, 2014, 9:35:58 AM6/17/14
to rubyonra...@googlegroups.com
Colin Law wrote in post #1149914:
> On 17 June 2014 13:34, Ronald Fischer <li...@ruby-forum.com> wrote:
>> In my schema, Idiom has an integer column kind. Given a certain card, I
>> (1) @card.idioms(:order => 'kind DESC')
>>
>> This doesn't seem to have any effect.
>
> What do you mean by not having any effect?

It means that they always come out in the same order (which,
accidentally, is *ascending* according to the kind values, which is
likely a consequence, that I create the Idiom objects with ascending
kind values, and so the probability is high that - with my small
development database - I just get them back in the order they were
created.

BTW, I looked at the result by running .inspect on the returned data,
and from this I found that it's not sorted descendingly.

> If you have a look in log/development.log you will see the query being
> run and check that it looks ok.

Oh, of course, I should have thought of this myself! I'll do that next
time I'm on the development host!

Ronald

Walter Lee Davis

unread,
Jun 17, 2014, 9:39:17 AM6/17/14
to rubyonra...@googlegroups.com

On Jun 17, 2014, at 9:30 AM, Ronald Fischer wrote:

> Walter Davis wrote in post #1149912:
>> On Jun 17, 2014, at 8:34 AM, Ronald Fischer wrote:
>> It sounds to me as though maybe all of your idioms have the same value
>> (or null) in their kind column.
>
> No, they have correct values (1, 2 and 3). Actually, the logic of the
> application ensures that there are only those values (I should this
> place into the model too).
>
> Does it mean that in your opinion, my attempt to sort them would be
> correct?
>

Your code is correct: some_reference.order('kind DESC') is the correct way to get the order you are asking for. Remember that if you only have three possible values, the implicit sort of the members within each kind will probably be the ID, all other things being equal. You should see the same behavior as if you entered this explicitly:

some_reference.order('kind DESC, id ASC')

Walter

>
> Ronald
>
> --
> Posted via http://www.ruby-forum.com/.
>
> --
> You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-ta...@googlegroups.com.
> To post to this group, send email to rubyonra...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/d8dad43e8c45f6895da580a710bdf0f7%40ruby-forum.com.

Hassan Schroeder

unread,
Jun 17, 2014, 10:04:44 AM6/17/14
to rubyonrails-talk
On Tue, Jun 17, 2014 at 6:38 AM, Walter Lee Davis <wa...@wdstudio.com> wrote:

> Your code is correct: some_reference.order('kind DESC') is the correct way to get the order you are asking for.

?? Not, the OP originally posted:

@card.idioms(:order => 'kind DESC')

which is 1) not equivalent, and 2) won't work.

--
Hassan Schroeder ------------------------ hassan.s...@gmail.com
http://about.me/hassanschroeder
twitter: @hassan

Walter Lee Davis

unread,
Jun 17, 2014, 10:17:26 AM6/17/14
to rubyonra...@googlegroups.com
Ooh, sorry, missed that whole side of the problem! Was that ever the way to do this, like say in Rails 1.5?

Walter

Scott Ribe

unread,
Jun 17, 2014, 10:26:14 AM6/17/14
to rubyonra...@googlegroups.com, Walter Lee Davis
On Jun 17, 2014, at 7:38 AM, Walter Lee Davis <wa...@wdstudio.com> wrote:

> Your code is correct: some_reference.order('kind DESC') is the correct way to get the order you are asking for. Remember that if you only have three possible values, the implicit sort of the members within each kind will probably be the ID, all other things being equal.

There is no "implicit" sort in SQL, the order within each kind will be indeterminate.

--
Scott Ribe
scott...@elevated-dev.com
http://www.elevated-dev.com/
(303) 722-0567 voice




Ronald Fischer

unread,
Jun 17, 2014, 1:53:23 PM6/17/14
to rubyonra...@googlegroups.com
Hassan Schroeder wrote in post #1149926:
> ?? Not, the OP originally posted:
>
> @card.idioms(:order => 'kind DESC')
>
> which is 1) not equivalent, and 2) won't work.


Oops!!!! I think that's it! Will check it on the next occasion.

(The OP is herewith ashamed)

Ronald Fischer

unread,
Jun 18, 2014, 4:15:42 AM6/18/14
to rubyonra...@googlegroups.com
Thanks to all contributors! Hassan Schroeder's sharp eye finally spotted
the culprit.

Matt Jones

unread,
Jun 18, 2014, 7:23:05 AM6/18/14
to rubyonra...@googlegroups.com


On Tuesday, 17 June 2014 07:35:05 UTC-5, Ruby-Forum.com User wrote:
I have in my model

class Card < ActiveRecord::Base
  has_many  :idioms,    dependent: :destroy
end

class Idiom < ActiveRecord::Base
  belongs_to :card
end

In my schema, Idiom has an integer column kind. Given a certain card, I
would like to have all associated idioms, but sorted in descending order
according to the 'kind' column.

I could do a

  @card.idioms.sort { .... }

but would prefer doing the sorting by the time the data is retrieved
from the database. I googled two suggestions:

(1) @card.idioms(:order => 'kind DESC')  
This doesn't seem to have any effect.

This doesn't do anything, because the association uses that single argument for something different (deciding whether to reload if already loaded).
 

(2) @card.idioms.all(:order => 'kind DESC')

This gives the error "wrong number of arguments (1 for 0)".

I think I could do a

Idiom.where(....)

and put an order restriction there, but I feel that Rails must have a
way to specify sorting when following associations, and maybe I just
made some silly mistake. Any ideas?

There are a couple ways to do this, depending on how often you need the data sorted in a particular way:

* adding an `order` onto your relation call will order the records:

@some_card.idioms.order(kind: :desc)

* adding a scope will do the same thing:

class Idiom < ActiveRecord::Base
  scope :by_kind, -> { order(kind: :desc) }
end

@some_card.idioms.by_kind

* or you can add the order directly to the association (building on the scope above):

class Card < ActiveRecord::Base
  has_many :idioms, -> { by_kind }, dependent: :destroy
end

@some_card.idioms # still sorted now

--Matt Jones

Reply all
Reply to author
Forward
0 new messages