LoginSignup
132
119

More than 5 years have passed since last update.

[Rails][Model] validate :if options

Posted at

5 Conditional Validation
Sometimes it will make sense to validate an object only when a given predicate is satisfied. You can do that by using the :if and :unless options, which can take a symbol, a string, a Proc or an Array. You may use the :if option when you want to specify when the validation should happen. If you want to specify when the validation should not happen, then you may use the :unless option.

validateを条件付きで行うには:if:unlessオプションを使う。
引数は、シンボル、文字列、Proc、配列のいずれかである。

5.1 Using a Symbol with :if and :unless
You can associate the :if and :unless options with a symbol corresponding to the name of a method that will get called right before validation happens. This is the most commonly used option.
class Order < ActiveRecord::Base
  validates :card_number, presence: true, if: :paid_with_card?

  def paid_with_card?
    payment_type == "card"
  end
end

シンボルを渡すときは、そのシンボル名のメソッドが呼ばれて、判定する。

5.2 Using a String with :if and :unless
You can also use a string that will be evaluated using eval and needs to contain valid Ruby code. You should use this option only when the string represents a really short condition.
class Person < ActiveRecord::Base
  validates :surname, presence: true, if: "name.nil?"
end

文字列を渡すときは、その文字列がevalで評価され、その結果で判定する。

5.3 Using a Proc with :if and :unless
Finally, it's possible to associate :if and :unless with a Proc object which will be called. Using a Proc object gives you the ability to write an inline condition instead of a separate method. This option is best suited for one-liners.
class Account < ActiveRecord::Base
  validates :password, confirmation: true,
    unless: Proc.new { |a| a.password.blank? }
end

Procを渡すと、Procが評価され、その結果で判定する。

5.4 Grouping Conditional validations
Sometimes it is useful to have multiple validations use one condition, it can be easily achieved using with_options.
class User < ActiveRecord::Base
  with_options if: :is_admin? do |admin|
    admin.validates :password, length: { minimum: 10 }
    admin.validates :email, presence: true
  end
end
All validations inside of with_options block will have automatically passed the condition if: :is_admin?

ひとつの条件判定で複数のvalidateをするときはwith_optionsでまとめることができる。

5.5 Combining Validation Conditions
On the other hand, when multiple conditions define whether or not a validation should happen, an Array can be used. Moreover, you can apply both :if and :unless to the same validation.
class Computer < ActiveRecord::Base
  validates :mouse, presence: true,
                    if: ["market.retail?", :desktop?]
                    unless: Proc.new { |c| c.trackpad.present? }
end
The validation only runs when all the :if conditions and none of the :unless conditions are evaluated to true.

逆に、複数の条件で判定して、一つのvalidationを実行するときは、if:に配列を渡すことができる。

132
119
0

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
132
119