Рельсы 6
Рельсы 6 добавляет upsert
и upsert_all
методы , которые обеспечивают эту функциональность.
Model.upsert(column_name: value)
[upsert] Он не создает экземпляров каких-либо моделей и не запускает обратные вызовы или проверки Active Record.
Рельсы 5, 4 и 3
Нет, если вы ищете оператор типа «upsert» (когда база данных выполняет обновление или оператор вставки в той же операции). По умолчанию Rails и ActiveRecord не имеют такой возможности. Однако вы можете использовать драгоценный камень upsert .
В противном случае вы можете использовать: find_or_initialize_by
или find_or_create_by
, которые предлагают аналогичную функциональность, хотя и за счет дополнительного обращения к базе данных, что в большинстве случаев вряд ли является проблемой. Поэтому, если у вас нет серьезных проблем с производительностью, я бы не стал использовать этот драгоценный камень.
Например, если не найдено ни одного пользователя с именем «Роджер», создается новый экземпляр пользователя с name
установленным значением «Роджер».
user = User.where(name: "Roger").first_or_initialize
user.email = "email@example.com"
user.save
В качестве альтернативы вы можете использовать find_or_initialize_by
.
user = User.find_or_initialize_by(name: "Roger")
В Rails 3.
user = User.find_or_initialize_by_name("Roger")
user.email = "email@example.com"
user.save
Вы можете использовать блок, но он запускается только в том случае, если запись новая .
User.where(name: "Roger").first_or_initialize do |user|
user.save
end
User.find_or_initialize_by(name: "Roger") do |user|
user.save
end
Если вы хотите использовать блок независимо от постоянства записи, используйте tap
результат:
User.where(name: "Roger").first_or_initialize.tap do |user|
user.email = "email@example.com"
user.save
end