Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NoMethodError for nil object on sort_by, and all objects exist

So I have a bunch of users, who all have user.dj_name attributes. It's a validated necessity on the model, but I'm still being cautious here because I'm running into problems.

I want to get a bunch of users, then order them by their dj_name. Something like this:

@djs = Event.all.map { |e| e.program.user }.sort_by {|x,y| x.dj_name <=> y.dj_name }

where it's pulling all DJs who have Events (shows). It fails with "NoMethodError: undefined method `dj_name' for nil:NilClass"

So I tried:

@djs = Event.all.map { |e| e.program.user }
@djs.compact.sort_by! {|x,y| x.dj_name <=> y.dj_name rescue nil}

And it doesn't sort. Without the "rescue nil" clause, I get the same error.

And if I do a reject! if the object is nil I get nothing.

> @djs.reject! {|d| d.nil? }
=> nil 

It seems like none of the objects in the array are nil, the sorting mechanism is giving me errors, and rescuing it just stops the sorting process and returns an unchanged array.

halp?

like image 845
mzemel Avatar asked Oct 03 '22 22:10

mzemel


2 Answers

Use the database sort for this kind of task. You can resume your queries by using:

Event.all(:include => {:program => :user}, :order => 'users.dj_name')

Decoupling this query would result in the include method making the join associations on your models and the order creating an ORDER BY on your query.

like image 193
MurifoX Avatar answered Oct 07 '22 18:10

MurifoX


Use sort!, not sort_by!.

sort_by! passes a single argument into its block. So, when you call .sort_by! {|x,y| ... }, y is always nil.

The purpose of sort_by! is to sort by keys instead of elements. The block gets a single element and must return the element's key to use for sorting.

In this code:

@djs.compact.sort_by! {|x,y| x.dj_name <=> y.dj_name rescue nil}

the block returns nil as a key for every element. As result, no sorting happens.

BTW, I agree with @MurifoX that in this particular case you should you database-provided sorting.

like image 21
Sergey Bolgov Avatar answered Oct 07 '22 17:10

Sergey Bolgov