class Invoice < ActiveRecord::Base
validate :expiration_date_cannot_be_in_the_past
def expiration_date_cannot_be_in_the_past
if expiration_date.present? && expiration_date < Date.today
errors.add(:expiration_date, "can't be in the past")
end
end
end
#app/validators/not_in_past_validator.rb
class NotInPastValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
if value.blank?
record.errors.add attribute, (options[:message] || "can't be blank")
elsif value <= Time.zone.today
record.errors.add attribute,
(options[:message] || "can't be in the past")
end
end
end
class InFutureValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
record.errors.add(attribute, (options[:message] || :in_future)) unless in_future?(value)
end
def in_future?(date)
date.present? && date > Time.zone.today
end
end
class Invoice < ActiveRecord::Base
validate :expiration_date_cannot_be_in_the_past
def expiration_date_cannot_be_in_the_past
if expiration_date.present? && expiration_date.past?
errors.add(:expiration_date, "can't be in the past")
end
end
end
validates(
:my_cool_timestamp_attribute,
inclusion: {
in: proc { Time.current.. },
message: "must be in the future when updating",
if: :changed?
},
on: :update,
)
6条答案
按热度按时间hsgswve41#
您的问题在Rails指南中(几乎)得到了准确的回答。
下面是他们给予的示例代码。这个类验证日期是在 * 过去 *,而你的问题是如何验证日期是在 * 未来 *,但调整它应该很容易:
字符串
a64a0gku2#
下面是设置自定义验证器的代码:
字符串
在你的模型中:
型
idfiyjo83#
最简单有效的解决方案是使用Rails的内置验证。就像这样验证它:
字符串
2j4z5cfb4#
我接受了@dankohn的回答,并更新为I18 n就绪。我还删除了
blank
测试,因为这不是该验证器的职责,并且可以通过将presence: true
添加到validates调用来轻松启用。更新后的类,现在命名为
in_future
,我认为它比not_in_past
更好字符串
现在将
in_future
密钥添加到本地化文件中。对于
errors.messages.in_future
下的所有字段,例如荷兰语:型
或
activerecord.errors.models.MODEL.attributes.FIELD.in_future
下的每个字段,例如对于荷兰语Vacancy
型号中的end_date
:型
x3naxklr5#
在rails 4+中,
DateTime
对象有future?
和past?
方法,因此更简单的答案是字符串
camsedfj6#
我从其他帖子中收集了一些东西来得到我的答案,但我认为我的结果可能比创建一个单独的验证器方法或类更直接,我认为我们可以绕过相对简单的验证。
proc
,这样它就可以在运行验证时加载,而不是在加载类时加载。也有一些建议给出了lambda(->(data)
),但这要求你在实际上不需要参数时表现得像有一个参数。if: :changed?
,这样只有在记录有更新的情况下才会出现验证错误。如果你想处理一个特定的字段,甚至只是时间戳字段,你可以通过组合字段名和changed?
- ex来使用rails方法。:my_cool_timestamp_attribute_changed?
个... is not included in the list
。on: :update
。rails的默认设置是在创建和更新时进行验证。字符串