Rails5 で validate の on オプションを使う
Ruby Ruby on Rails
Published: 2019-06-13

やったこと

Rails5 で validate の on オプションを使います。

確認環境

$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]

$ rails --version
Rails 5.2.3

調査

app/models/task.rb

class Task < ApplicationRecord
  validates :name , uniqueness: true, on: :task_setup
end

task.name に “name1” で1件登録します。

$ rails c
Running via Spring preloader in process 23605
Loading development environment (Rails 5.2.3)
irb(main):001:0> a1 = Task.new
=> #<Task id: nil, created_at: nil, updated_at: nil, name: nil>
irb(main):002:0> a1.name = "name1"
=> "name1"
irb(main):003:0> a1.save
   (0.1ms)  begin transaction
  Task Create (0.5ms)  INSERT INTO "tasks" ("created_at", "updated_at", "name") VALUES (?, ?, ?)  [["created_at", "2019-06-12 12:50:53.647258"], ["updated_at", "2019-06-12 12:50:53.647258"], ["name", "name1"]]
   (0.8ms)  commit transaction
=> true

save メソッドに context で指定すると、保存に失敗します。

irb(main):005:0> a2 = Task.new
=> #<Task id: nil, created_at: nil, updated_at: nil, name: nil>
irb(main):006:0> a2.name = "name1"
irb(main):007:0> a2.save(context: :task_setup)
   (0.1ms)  begin transaction
  Task Exists (0.2ms)  SELECT  1 AS one FROM "tasks" WHERE "tasks"."name" = ? LIMIT ?  [["name", "name1"], ["LIMIT", 1]]
   (0.1ms)  rollback transaction
=> false

context を指定せずに save すると、保存できました。

irb(main):008:0> a2.save()
   (0.1ms)  begin transaction
  Task Create (0.4ms)  INSERT INTO "tasks" ("created_at", "updated_at", "name") VALUES (?, ?, ?)  [["created_at", "2019-06-12 12:52:31.539434"], ["updated_at", "2019-06-12 12:52:31.539434"], ["name", "name1"]]
   (0.8ms)  commit transaction
=> true

参考