同一項目に同一バリデータによるバリデーションを複数種書きたいんです
max_salaryによってjob_titleのバリデーションを変えたいなあと思った場合、validates
の記述自体を分けて↓こう書けばよい。
class Job < ActiveRecord::Base self.primary_key = :job_id validates :job_title, length: {maximum: 5, if: ->{max_salary <= 1000}} validates :job_title, length: {maximum: 10, if: ->{max_salary > 1000}} end j = Job.new(job_title: 'abcdefg', max_salary: 1000) p j.valid? ? "correct" : j.errors.full_messages # => ["Job title is too long (maximum is 5 characters)"] j = Job.new(job_title: 'abcdefg', max_salary: 1001) p j.valid? ? "correct" : j.errors.full_messages # => "correct"
1つにまとめて↓こう書くと失敗する。
class Job < ActiveRecord::Base self.primary_key = :job_id validates :job_title, length: {maximum: 5, if: ->{max_salary <= 1000}}, length: {maximum: 10, if: ->{max_salary > 1000}} end j = Job.new(job_title: 'abcdefg', max_salary: 1000) p j.valid? ? "correct" : j.errors.full_messages # => "correct" j = Job.new(job_title: 'abcdefg', max_salary: 1001) p j.valid? ? "correct" : j.errors.full_messages # => "correct"
1つのvalidates
で同じバリデータを複数回記述すると、最後に記述したものが有効になってしまう。だから↓こう書くと当然すべてエラーになる。
class Job < ActiveRecord::Base self.primary_key = :job_id validates :job_title, length: {maximum: 5, if: ->{max_salary <= 1000}}, length: {maximum: 10, if: ->{max_salary > 1000}}, length: {maximum: 3} end j = Job.new(job_title: 'abcdefg', max_salary: 1000) p j.valid? ? "correct" : j.errors.full_messages # => ["Job title is too long (maximum is 5 characters)"] j = Job.new(job_title: 'abcdefg', max_salary: 1001) p j.valid? ? "correct" : j.errors.full_messages # => ["Job title is too long (maximum is 5 characters)"]
でも複数のvalidates
に書き分ければクリアできてしまう問題なので、将来的には↑この書き方でも意図通りにバリデーションしてくれるようになる可能性も微レ存?