78
82

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

「いずれかのカラムが空でなければ良い」というバリデーション

Last updated at Posted at 2015-09-27

背景

年末も近づいてきて年賀状の送り先を管理しないといけないなぁ、と思ったので、簡易のアドレス帳サービスでも作ってみようとしたわけです。
そこで、連絡先のモデルとして、

app/models/contact.rb
class Contact < ActiveRecord::Base
  validates :email, presence: true
  validates :phone, presence: true
end

みたいにしたんですね。ここで

住所address は必須だろう、けれど、メールアドレス emailphone はどちらかでいい。

という要求が出てきたわけです。

ifvalidates を制御する方法

app/models/contact.rb
class Contact < ActiveRecord::Base
  validates :email, presence: true, if: -> { phone.blank? }
  validates :phone, presence: true, if: -> { email.blank? }
end

みたいにすれば、それぞれが他方が無い時のみにバリデーションを実施できます。

ですが、これは何を判断しているのかが、ちょっとわかりづらい。。。
そして、両方が空だった時に、contact.errors に2つのメッセージが入ってしまい、いずれもが必須入力のように見えてしまいます。

validatesの対象になるメソッドを定義する

何言ってるかよくわからないと思うので、コードを載せます。

app/models/contact.rb
class Contact < ActiveRecord::Base
  # シンボルで指定する。
  validates :email_or_phone, presence: true
  
  private
    def email_or_phone
      email.presence or phone.presence
    end
end

としておくと、invalid時のエラーメッセージは1つに集約できます。

国際化についても、

config/locales/ja.yml
activerecorde:
  attributes:
    contact:
     email: メールアドレス
     phone: 電話番号
      email_or_phone: メールアドレスまたは電話番号

とすれば、エラーメッセージもそれっぽく見せられます。

おわりに

それっぽいgemやtipsを見つけられなかったので、教えてもらえると嬉しいです。

78
82
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
78
82

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?