active_record: find vs find_by

Maybe you have used activerecord find to retrieve a record from your database:

obj.find(id)  

if the id does not exist is going to through an exception like:

ActiveRecord::RecordNotFound:  
       Couldn't find Obj without an ID

but if you are expecting this return nil if the id does not exist use:

obj.find_by(id: id)  

if the id does not exist the output is going to be:

nil  

This is because internaly those methods works like:

find

def find(*args)  
  return super if block_given?
  find_with_ids(*args)
end  
def find_with_ids(*ids)  
  raise UnknownPrimaryKey.new(@klass) if primary_key.nil?

  expects_array = ids.first.kind_of?(Array)
  return ids.first if expects_array && ids.first.empty?

  ids = ids.flatten.compact.uniq

  case ids.size
  when 0
    raise RecordNotFound, "Couldn't find #{@klass.name} without an ID"
  when 1
    result = find_one(ids.first)
    expects_array ? [ result ] : result
  else
    find_some(ids)
  end
rescue RangeError  
  raise RecordNotFound, "Couldn't find #{@klass.name} with an out of range ID"
end  

find_by

def find_by(arg, *args)  
  where(arg, *args).take
rescue RangeError  
  nil
end  

Hope you find(it) helpful! :v:

Victor Velazquez

Coder, Musician, Startups, Passionate Dancer & Life Lover. Software Engineer at MagmaLabs, Co-founder of Web Dev Talks, Co-founder of Voltaire, Co-founder of Paqkit, Ex-co-founder of Zaznova.

Subscribe to The zazvick's blog

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!