pif*_*ffy 6 ruby validation ruby-on-rails date
我正在ActiveRecord中编写自定义验证器,以便截止日期有意义:
validate :deadline_is_possible?
def deadline_is_possible?
if deadline > begins_at
errors.add(:deadline, 'must be possible')
end
end
Run Code Online (Sandbox Code Playgroud)
然而,这会为nil:NilClass生成"NoMethodError:undefined method`>'.我事件试图将日期变成字符串,如:
def deadline_is_possible?
if deadline.to_s > begins_at.to_s
errors.add(:deadline, 'must be possible')
end
end
Run Code Online (Sandbox Code Playgroud)
虽然它不会产生错误,但也不起作用.
我还宣布了其他验证者(例如
def begins_at_is_date?
if !begins_at.is_a?(Date)
errors.add(:begins_at, 'must be a date')
end
end
Run Code Online (Sandbox Code Playgroud)
工作还可以.
小智 14
您可以使用比较:
validates :deadline, comparison: { greater_than: :begins_at }
Run Code Online (Sandbox Code Playgroud)
文档: https: //guides.rubyonrails.org/active_record_validations.html#comparison
如果其中一个日期为零,您可能需要处理。您可以将这些设置为截止日期数据库中的默认值,或者执行以下操作:
validate :deadline_is_possible?
def deadline_is_possible?
return if [deadline.blank?, begins_at.blank?].any?
if deadline > begins_at
errors.add(:deadline, 'must be possible')
end
end
Run Code Online (Sandbox Code Playgroud)
您可以添加自己的验证器:
class AfterDateValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
return if value.blank?
other_date = record.public_send(options.fetch(:with))
return if other_date.blank?
if value < other_date
record.errors.add(attribute, (options[:message] || "must be after #{options[:with].to_s.humanize}"))
end
end
end
Run Code Online (Sandbox Code Playgroud)
并在模型中使用它:
validates :invited_on, presence: true
validates :selected_on, presence: true, after_date: :invited_on
Run Code Online (Sandbox Code Playgroud)