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

Ruby on-RailsActiverecord

Ruby on-Rails Problem Overview


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?

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

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 - Ruby on-Rails

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

Solution 3 - Ruby on-Rails

Depending of what you want to do, you might use a block:

widget = find_or_create_by(widgetid: "12345") do |widget|
  widget.param2 = "folk"
  if widget.new_record?
    # Code for a new widget.
  else
    # Code for an existing widget.
  end
end

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDaveView Question on Stackoverflow
Solution 1 - Ruby on-RailsShadwellView Answer on Stackoverflow
Solution 2 - Ruby on-RailsFlavio WuenscheView Answer on Stackoverflow
Solution 3 - Ruby on-RailsTim ScottView Answer on Stackoverflow