ActiveRecord finders behave differently for various types of finders. Suppose you have a model called Account. Here are the ways you can get a record with id 34 in the `accounts` table.

acc = Account.find(34)
acc = Account.where(:id => 34).first
acc = Account.where(:id => 34)

Suppose a record with id = 34 does not exist in `accounts` table. Most programmers would think that the finders will throw ActiveRecord::RecordNotFound exception in all cases. No, thats not the behavior here. In the first case, using ‘find’ method returns ActiveRecord::RecordNotFound exception. Where as in the second case using ‘where’ method, it returns nil object. In the third case it returns an empty array []

ruby-1.9.2-p180 :001 > Account.find(34)
ActiveRecord::RecordNotFound: Couldn’t find Account with ID=34
ruby-1.9.2-p180 :002 > Account.where(:id => 34).first
=> nil
ruby-1.9.2-p180 :003 > Account.where(:id => 34)
=> []

If we find records using ‘find’ method, it is assumed that we have prior knowledge of the table ‘accounts’ and the primary key values. So, if there is no record with that id, an exception is thrown. If we use ‘where’ method to find records, we are querying based on some conditions. If the query finds anything that matches our conditions, it returns the result. If it cannot find any record that matches our conditions, it returns an empty array or nil object.

Empty array is returned when we fire a non-singular query (as in third case). A Nil object is returned if we fire a singular query. This behavior have to be kept in mind when find records and apply conditions on them, in the Rails controllers.

Tags: , ,

Leave a comment