Rails ActiveRecord: How do I know if find_or_create_by found or created?

If I do

widget = Widget.find_or_create_by_widgetid(:widgetid => "12345", :param2 => "folk") 

etc. then how do I tell if newobj is a found or newly created Widget? Is there something I can test conditionally on widget that will tell me?


Solution 1:

I don't believe there's a way to tell if the object is newly created or was already there. You could use find_or_initialize_by_widgetid instead which doesn't save the new object. You can then check widget.new_record? which will tell you whether the object has been saved or not. You'd have to put a save call in the block of code for a new object but as you want to make that check anyway it shouldn't ruin the flow of the code.

So:

widget = find_or_initialize_by_widgetid(:widgetid => "12345", :param2 => "folk")
if widget.new_record?
  widget.save!
  # Code for a new widget
else
  # Code for an existing widget
end

Solution 2:

Rails 4+

find_or_create_by(attributes, &block)

Now this method accepts a block, which is passed down to create, so I'd go with:

widget = Widget.find_or_create_by(:widgetid => "12345", :param2 => "folk") do |w|
  # if you got in here, this is a new widget
end

Another way to do this in Rails 4+ would be:

widget = Widget.where(:widgetid => "12345", :param2 => "folk").first_or_initialize

if widget.new_record?
  # this is a new widget
end