I am using below code to upsert
my Model which works correctly but is verbose. I wanted to shorten it by using find_or_create_by
, create_with
and optional chaining but it is not working as expected.
Can someone please advice...
Verbose Code which works -
user_attr = {
first_name: 'Scarlett',
last_name: 'Johansson',
profession: 'Actress',
address: 'Los Angeles'
}
....
existing_user = User.find_by(first_name: user_attr.fetch(:first_name),
last_name: user_attr.fetch(:last_name))
if existing_user
existing_user.update!(user_attr)
else
User.create!(user_attr)
end
Output:
# => #<User id: 2, first_name: "Scarlett", last_name: "Johansson", profession: "Actress", address: "Los Angeles">
Shorter version which does not return correct output:
User
.create_with(user_attr)
.find_or_create_by(first_name: user_attr.fetch(:first_name),
last_name: user_attr.fetch(:last_name))
Reference - https://apidock.com/rails/v4.0.2/ActiveRecord/Relation/find_or_create_by
CodePudding user response:
You could find_or_create_by
first, then update
:
user = User.find_or_create_by!(first_name: 'Scarlett', last_name: 'Johansson')
user.update!(profession: 'Actress', address: 'Los Angeles')