Skip to content

Instantly share code, notes, and snippets.

@bassemawhoob
Last active July 19, 2024 13:42
Show Gist options
  • Save bassemawhoob/f47779eca19cfe6eedd781a498ba42e4 to your computer and use it in GitHub Desktop.
Save bassemawhoob/f47779eca19cfe6eedd781a498ba42e4 to your computer and use it in GitHub Desktop.
An ActiveRecord extension to update a record if found, otherwise create it
# frozen_string_literal: true
module ActiveRecord
class Base
# Create or update a record by field (or fields). This will look for each field name as a key in the
# options hash.
# @example
# # If a user with that email exists then update his name and birthdate, else create him
# attributes={name: "Bassem Mawhoob", email: "test@example.com", :birthdate=>'1980/01/01'}
# User.create_or_update_by(:email, attributes)
# @example
# # If a user with that name and birthdate exists then update his email, else create him
# attributes={name: "Bassem Mawhoob", email: "test@example.com", :birthdate=>'1980/01/01'}
# User.create_or_update_by([:name, :birthdate], attributes)
def self.create_or_update_by(condition_keys = :id, attributes = {})
condition_pairs = [*condition_keys].index_with do |key|
(attributes.delete(key) || attributes.delete(key.to_s))
end
record = find(:first, conditions: condition_pairs) || new
attributes.merge!(condition_pairs) if record.new_record?
record.assign_attributes(attributes)
record.save!
record
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment