Take the 2-minute tour ×

I have a model MyModel with a method to return a specific record (see logic below).

def self.find_future_rec   #note2
  rec = find(rand(MyModel.count)+1)   #note1
  while rec.nil? | (rec.expdate<Date.today)
    rec = find(rand(MyModel.count)+1)
  return rec

Every record of MyModel class has a variable expdate of Date class. (I know this is a horrible way to find a record, this is more for my own edification and also some test code.)

  1. This method will iterate through several undesirable records before finding an appropriate record, but the record returned is always the one found at note 1, the first record queried. Is there some lazy assignment thing going on here?
  2. I had to add self at note2 to be able to call the method in a static context. Is this the correct interpretation?
share|improve this question
What makes you think your loop is iterating at all? –  mu is too short Dec 21 '12 at 0:06
In my Terminal I can see multiple db hits finding undesirable records before stopping after finding a desirable one. –  yamori Dec 21 '12 at 16:37
You'll have to add more information (such as some debugging output of rec.expdate before, inside, and after the loop). –  mu is too short Dec 21 '12 at 18:07
add comment

2 Answers

up vote 1 down vote accepted

The find method never returns nil when you give it a single ID to find: if it can't find the record you're asking for, it raises an ActiveRecord::RecordNotFound exception. So, rec is always non-nil and rec.nil? is always false. That means that your loop is really like this:

while rec.expdate < Date.today

If your loop is always returning the rec from #note1 then you're never entering the while loop at all and you're always getting a desirable MyModel on the first try.

Other points to consider:

  1. Sometimes things get deleted so Model.count + 1 is not necessarily the maximum ID.
  2. find raises an exception to indicate failure so you need to rescue ActiveRecord::RecordNotFound rather than check for nil.
share|improve this answer
add comment

You are using | which is a boolean OR. Try using or or ||.

Adding self to make a method a class method ("static" is a decent approximation) is indeed one of the correct ways to approach this.

share|improve this answer
| is (usually) a bitwise OR but | and || are the same for booleans. –  mu is too short Dec 21 '12 at 0:06
add comment

Your Answer


