- create! と違い create は例外を起こさない
- 返り値が model class の instance になるので、 persisted? ( 永続化されたかどうか? ) を聞くと良さそうだ。
- SQLレベルで失敗した場合は例外扱いになり、返り値は得られないようだ。
# -------------------------
# 作成成功ケース
# -------------------------
succeeded_created = User.create(name: "yy")
# (1.0ms) BEGIN
# User Exists (1.4ms) SELECT 1 AS one FROM `users` WHERE `users`.`name` = BINARY 'yy' LIMIT 1
# User Create (1.4ms) INSERT INTO `users` (`name`, `created_at`) VALUES ('yy', '2020-02-13 23:42:17')
# (4.9ms) COMMIT
succeeded_created.persisted?
# => true
succeeded_created.valid?
# User Exists (1.0ms) SELECT 1 AS one FROM `users` WHERE `users`.`name` = BINARY 'yy' AND `users`.`id` != 83 LIMIT 1
# => true
succeeded_created.invalid?
# User Exists (2.2ms) SELECT 1 AS one FROM `users` WHERE `users`.`name` = BINARY 'yy' AND `users`.`id` != 83 LIMIT 1
# => false
succeeded_created.errors
#=> #<ActiveModel::Errors:0x000056396e61bc70
# @base=#<User:0x000056396e816480 id: 83, name: "yy", created_at: Thu, 13 Feb 2020 23:45:53 UTC +00:00>,
# @details={},
# @messages={}>
succeeded_created.errors.present?
#=> false
# -------------------------
# バリデーションによる作成失敗ケース
# -------------------------
failed_created = User.create(name: "yy")
# (0.6ms) BEGIN
# User Exists (1.2ms) SELECT 1 AS one FROM `users` WHERE `users`.`name` = BINARY 'yy' LIMIT 1
# (1.0ms) ROLLBACK
failed_created.persisted?
# => false
failed_created.errors
# => #<ActiveModel::Errors:0x0000563973bd4888
# @base=#<User:0x0000563973bd9d10 id: nil, name: "yy", created_at: nil>,
# @details={:name=>[{:error=>:taken, :value=>"yy"}]},
# @messages={:name=>["はすでに存在します"]}>
failed_created.errors.present?
# => true
failed_created.valid?
# User Exists (1.2ms) SELECT 1 AS one FROM `users` WHERE `users`.`name` = BINARY 'yy' LIMIT 1
=> false
failed_created.invalid?
# User Exists (1.7ms) SELECT 1 AS one FROM `users` WHERE `users`.`name` = BINARY 'yy' LIMIT 1
=> true
# -----------------------------
# SQL エラーが発生したケース
# -----------------------------
sql_failed_created = User.create(name: "yy")
# (0.8ms) BEGIN
# User Create (6.1ms) INSERT INTO `users` (`name`, `created_at`) VALUES ('yy', '2020-02-13 23:55:11')
# (5.7ms) ROLLBACK
#ActiveRecord::RecordNotUnique: Mysql2::Error: Duplicate entry 'yy' for key 'index_users_on_name': INSERT INTO `users` (`name`, `created_at`) VALUES ('yy', '2020-02-13 23:55:11')
#
# Caused by Mysql2::Error: Duplicate entry 'yy' for key 'index_users_on_name'
sql_failed_created.persisted?
# NoMethodError: undefined method `persisted?' for nil:NilClass
Original by Github issue
チャットメンバー募集
何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。