Navigation

ADS specializes in using Ruby on Rails to build advanced, scalable, database-backed web sites for organizations of all sizes. Find out more at our website.

Atlantic Dominion Solutions

!nil != not nil

By: Damien McKenna | Tags:

Here’s an odd one for you, and I leave it up to you to decide whether it is a bug or a feature.

A great little shortcut to be able to do in find methods on your models is for when you know a field is null you can just do e.g.:

Product.find_all_by_category_id_and_description(42, nil)

This will return a list of all products in category 42 with no description, as you can see from the debug output:

SELECT * FROM `products` WHERE (`products`.`category_id` = 42 AND `products`.`description` IS NULL)

Great, nice and simple.

So what if you want to find all products in category 42 that have a description? Normal logic might suggest something like this:

Product.find_all_by_category_id_and_description(42, !nil)

That logic works in Ruby itself, but Rails does something funny when it comes to piping that into a query:

SELECT * FROM `products` WHERE (`products`.`category_id` = 42 AND `products`.`description` = 1)

Huh? Well that doesn’t work. Given that Rails is smart enough to recognize that the “nil” passed in should get converted to “IS NULL” in the query, it’s disappointing that it doesn’t do likewise for “!nil”.

Share this post

Random Posts

You can skip to the end and leave a response. Pinging is currently not allowed.

Print This Post Print This Post

4 Responses to “!nil != not nil”

On January 25th, 2008 at 12:10 pm Peter Cooper said:

I agree. !nil becomes ‘true’. Perhaps you should write a patch so that true becomes IS NOT NULL. I think it would get popular support, although this is not a common usage.

On January 25th, 2008 at 12:49 pm Shadowfiend said:

The problem is that this would require handling boolean fields appropriately (as for them true should be handled as true) and possibly dealing with situations where the field is not nullable, as the programmer may be anticipating an = 1 there, as well. It’s realizing that this is the same as typing find_all_by_category…(42, true) that complicates the issue. Perhaps if there was a constant NOT_NULL or something of the sort that was a particular type of object that could be recognized, that would make more sense.

On January 25th, 2008 at 3:06 pm Brian Terlson said:

As other’s have mentioned, Rails can’t really be smart enough to notice the difference between true and !nil, since ruby considers them equal. The alternative is to not use the dynamic finders… find(:all, :conditions => ['category_id=42 and description IS NOT NULL']) for example.

On January 27th, 2008 at 1:34 am Josh said:

I’m trying to do the same thing, select all where description is not null. I Brians’S his code but I get an error. I ended up adding a boolean to the table that indicates whether its entered, but I would like to find a solution to select entries where properties are anything but nil!

Leave a Reply