[英]How can I do conditional validation in a Ruby on Rails Model?
我有可以participants
的study
。 我有一個simple_form ,用戶可以在其中添加參與者。 它看起來有點像一張桌子:
name | company | email OR mobile | timezone
name | company | email OR mobile | timezone
name | company | email OR mobile | timezone
默認情況下,該屏幕具有三個字段集行,並且用戶可以根據需要添加更多行。 每行是一個參與者。
我希望我的participant
模型僅驗證已填寫的行,而忽略空白行,因為即使我們默認向用戶顯示三行,也不是全部都是必填字段。
這是app/models/participants.rb
的相關部分。
class Participant < ApplicationRecord
belongs_to :study
validates :name, presence: true
validates :company, presence: true
validates :time_zone, presence: true
if :channel == 'sms'
validates :mobile_number, presence: true
elsif :channel == 'email'
validates :email, presence: true
end
end
在participants_controller.rb
我有:
def index
3.times { @study.participants.build } if @study.participants.length.zero?
end
問題是我得到一個錯誤,因為simple_form認為所有三個字段都是必需的,而不僅僅是第一行。
Rails的驗證器接受以下條件:
validates :mobile_number, presence: true, if: Proc.new { |p| p.study.channel == 'sms' }
validates :email, presence: true, if: Proc.new { |p| p.study.channel == 'email' }
默認情況下,所有輸入都是必需的。 當表單對象包含ActiveModel :: Validations(例如,在Active Record模型中發生)時,僅當存在狀態驗證時才需要字段。 否則,“簡單表單”會將字段標記為可選。 出於性能原因,在使用條件選項(例如:if和:unless)的驗證中將跳過此檢測。
當然,可以根據需要覆蓋任何輸入的必需屬性:
<%= simple_form_for @user do |f| %>
<%= f.input :name, required: false %>
<%= f.input :username %>
<%= f.input :password %>
<%= f.button :submit %>
<% end %>
嘗試根據需要放置所有輸入:false 。 這應該允許跳過simple_form驗證,並且數據進入控制器,並且可以對模型進行過濾或/和驗證,以及在持久化之前要執行的所有其他操作。
在模型類中,可以使用幾種驗證方式,例如:
您還可以使用:if和:unless選項,並在符號上使用與方法名稱相對應的符號,該名稱將在驗證發生之前立即被調用。 這是最常用的選項。
例如
class Participant < ApplicationRecord
belongs_to :study
validates :name, presence: true
validates :company, presence: true
validates :time_zone, presence: true
validates :mobile_number, presence: true if: :channel_is_sms?
validates :email, presence: true if: :channel_is_email?
def channel_is_sms?
channel == "sms"
end
def channel_is_email?
channel == "email"
end
end
或者,您也可以在所有需要驗證的地方使用自定義驗證器 。 例如
class MyValidator < ActiveModel::Validator
def validate(record)
unless record.channel == 'sms'
...
... actions here
...
end
end
end
class Person
include ActiveModel::Validations
validates_with MyValidator
end
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.