やったこと
Rails の ActiveRecord で update を実行するときに、 validate が呼び出されるのかを検証してみます。
確認環境
$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]
$ rails --version
Rails 5.2.3
調査
validate が呼び出されているかを調べる
app/models/task.rb
class Task < ApplicationRecord
validate :hoge
def hoge
logger.debug("custom validate: #{__method__}")
end
end
実行結果
$ rails c
Running via Spring preloader in process 29317
Loading development environment (Rails 5.2.3)
irb(main):001:0> Task.all
Task Load (1.9ms) SELECT "tasks".* FROM "tasks" LIMIT ? [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Task id: 4, created_at: "2019-06-12 12:50:53", updated_at: "2019-06-12 12:50:53", name: "name1">, #<Task id: 5, created_at: "2019-06-12 12:52:31", updated_at: "2019-06-12 12:52:31", name: "name1">]>
irb(main):002:0> t = Task.find(4)
Task Load (0.2ms) SELECT "tasks".* FROM "tasks" WHERE "tasks"."id" = ? LIMIT ? [["id", 4], ["LIMIT", 1]]
=> #<Task id: 4, created_at: "2019-06-12 12:50:53", updated_at: "2019-06-12 12:50:53", name: "name1">
irb(main):003:0> t.update(name: "name22")
(0.1ms) begin transaction
custom validate: hoge
Task Update (0.5ms) UPDATE "tasks" SET "updated_at" = ?, "name" = ? WHERE "tasks"."id" = ? [["updated_at", "2019-07-14 15:51:29.933901"], ["name", "name22"], ["id", 4]]
(3.5ms) commit transaction
=> true
update が実行されると validate も実行されていることが分かります。
validate の unique 制約が働くのか調べる
app/models/task.rb
class Task < ApplicationRecord
validates :name , uniqueness: true, presence: true
validate :hoge
def hoge
logger.debug("custom validate: #{__method__}")
end
end
実行結果
$ rails c
Running via Spring preloader in process 30205
Loading development environment (Rails 5.2.3)
irb(main):001:0> Task.all
Task Load (1.4ms) SELECT "tasks".* FROM "tasks" LIMIT ? [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Task id: 4, created_at: "2019-06-12 12:50:53", updated_at: "2019-07-14 16:01:58", name: "name2">, #<Task id: 5, created_at: "2019-06-12 12:52:31", updated_at: "2019-06-12 12:52:31", name: "name1">]>
irb(main):002:0> task = Task.find(4)
Task Load (0.2ms) SELECT "tasks".* FROM "tasks" WHERE "tasks"."id" = ? LIMIT ? [["id", 4], ["LIMIT", 1]]
=> #<Task id: 4, created_at: "2019-06-12 12:50:53", updated_at: "2019-07-14 16:01:58", name: "name2">
irb(main):003:0> task.update(name: "name1")
(0.1ms) begin transaction
Task Exists (0.2ms) SELECT 1 AS one FROM "tasks" WHERE "tasks"."name" = ? AND "tasks"."id" != ? LIMIT ? [["name", "name1"], ["id", 4], ["LIMIT", 1]]
custom validate: hoge
(0.1ms) rollback transaction
=> false
unique 制約のバリデーションが効いていることが分かります。