c-hive / guides

Guides for code style, way of working and other development concerns
MIT License
26 stars 5 forks source link

Add chapter to Rails about first_or_create & co #44

Open thisismydesign opened 4 years ago

thisismydesign commented 4 years ago

Initial notes:

Keep in mind caveats of first_or_create, find_or_create_by, first_or_initialize, find_or_initialize_by and upsert

where and first_or_* can be combined to be the same as find_or_*_by

User.where(name: "Roger").first_or_initialize == User.find_or_initialize_by(name: "Roger")
User.where(name: "Roger").first_or_create == User.find_or_create_by(name: "Roger")

The body only runs if the object is newly created

User.where(id: id).first_or_create! do |user|
  user.assign_attributes(attributes)
end

User.find_or_create_by!(id: id) do |user|
  user.assign_attributes(attributes)
end

User.where(id: id).first_or_initialize do |user|
  user.assign_attributes(attributes)
  user.save!
end

User.find_or_initialize_by(id: id) do |user|
  user.assign_attributes(attributes)
  user.save!
end

Passed attributes are only assigned if the object is newly created

User.where(id: id).first_or_create!(attributes)
User.where(id: id).first_or_initialize(attributes)

find_or_create_by(nil) will get the first entity while find_or_create_by(id: nil) will create a new one

User.find_or_create_by(nil) != User.find_or_create_by(id: nil)

Valid but broken?

User.where(id: id).find_or_initialize_by