Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

First_or_create with update on match?

I really like the first_or_create method:

# Find the first user named Scarlett or create a new one with a particular last name.
User.where(:first_name => 'Scarlett').first_or_create(:last_name => 'Johansson')
# => <User id: 2, first_name: 'Scarlett', last_name: 'Johansson'>

I was wondering how I could also have this update the User with the last_name 'Johannson' if it's not present or different. Looking for the briefest way of doing this. A one liner similar to the above would be ideal.

One possible approach is using first_or_initialize combined with update_attributes. The only concern I have with this approach is that it would run an update even if there were a 100% match on the fields provided.

like image 405
bgcode Avatar asked May 01 '13 18:05

bgcode


2 Answers

Zaid is VERY close to correct.

User.where(first_name: 'Scarlett').first_or_create.update(last_name: 'Johansson')

Detailed differences here. (Note: this is for Rails 3+ and Rails 4+)

  1. The difference between first_or_create vs. first_or_initialize is that _initialize uses the .new method and does not save the record vs .create and auto saves it.

  2. The difference between .update vs. .update_attributes, .update_attributes is what you use when you have a hash of values, typically coming from a form submit like params. On the other hand,.update lets you easily specify each attribute as shown above (field_column: value, field_column2: value2), etc.

And just like Zaid said, but it applies to both .update and .update_attributes, rails database updates "...only hits the database if there are changes to be made..."

like image 83
Eric Wanchic Avatar answered Oct 21 '22 07:10

Eric Wanchic


first_or_initialize with update_attributes should be fine. Rails is smart enough that update_attributes only hits the database if there are changes to be made (which you should be able to confirm for yourself using the console/logs).

like image 36
zkcro Avatar answered Oct 21 '22 09:10

zkcro