18 Mar 2009

Use exists? to check if a record exists or not

You want to know if a record exists with the email address ‘john@example.com’ or not? Most common implementation I see is this

if User.find(:first, :conditions => ["email =?",'john@example.com'])
  # ..
end

Above solution works but it is not a very good solution. A better solution would be

if User.exists?(["email =?",'john@example.com'])
  # ..
end

Why exists? is a better solution

When you perform User.find(:first, :conditions => {}) then a sql statement is issued. But ,more importantly, if a record is found then a model instance is created. Well ,in this particular case, the intent was just to check if a record exists or not. All the cost associated with instantiating the found record is wasted.

When you use User.exists? method then a sql statement is issued and depending on the result either true or false is returned. An instance of the model is NOT created even if a record is found. So using User.exists? saves the cost associated with model creation.

The second reason why User.exists? is a better solution is because it lets others know the intent of the programmer. User.exists? clearly tells that all I care is whether a record exists or not. Compare that to if User.find() does not tell much about the intent of the programmer.

How do you detect if a record is instantiated or not

The sql statement generated by both User.first() and User.exists? is same. So someone asked how did I find out in one case a model was getting instantiated.

callback after_initialize to rescue. Any time a model is instantiated Rails invokes a method called after_initialize . To see the different put this method in your model .

def after_initialize
  puts "initialized"
end

Now in your script/console you will see the “initialized” message when an instance of the model is created.