有什么方法可以验证 Rails 中的单个属性?
就像是:
ac_object.valid?(attribute_name)
有什么方法可以验证 Rails 中的单个属性?
就像是:
ac_object.valid?(attribute_name)
有时会有相当昂贵的验证(例如,需要执行数据库查询的验证)。在这种情况下,您需要避免使用valid?
,因为它的功能远远超出您的需要。
有一个替代解决方案。可以使用的validators_on
方法ActiveModel::Validations
。
validators_on(*attributes) 公共
列出所有用于验证特定属性的验证器。
根据它您可以手动验证您想要的属性
例如,我们只想验证title
of Post
:
class Post < ActiveRecord::Base
validates :body, caps_off: true
validates :body, no_swearing: true
validates :body, spell_check_ok: true
validates presence_of: :title
validates length_of: :title, minimum: 30
end
哪里no_swearing
和spell_check_ok
是极其昂贵的复杂方法。
我们可以做到以下几点:
def validate_title(a_title)
Post.validators_on(:title).each do |validator|
validator.validate_each(self, :title, a_title)
end
end
这将仅验证 title 属性而不调用任何其他验证。
p = Post.new
p.validate_title("")
p.errors.messages
#=> {:title => ["title can not be empty"]
我不完全相信我们应该validators_on
安全使用,所以我会考虑在validates_title
.
您可以在模型中实现自己的方法。像这样的东西
def valid_attribute?(attribute_name)
self.valid?
self.errors[attribute_name].blank?
end
或将其添加到ActiveRecord::Base
我最终以@xlembouras 的回答为基础,并将此方法添加到我的ApplicationRecord
:
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
def valid_attributes?(*attributes)
attributes.each do |attribute|
self.class.validators_on(attribute).each do |validator|
validator.validate_each(self, attribute, send(attribute))
end
end
errors.none?
end
end
然后我可以在控制器中做这样的事情:
if @post.valid_attributes?(:title, :date)
render :post_preview
else
render :new
end
基于@coreyward 的回答,我还添加了一个validate_attributes!
方法:
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
def valid_attributes?(*attributes)
attributes.each do |attribute|
self.class.validators_on(attribute).each do |validator|
validator.validate_each(self, attribute, send(attribute))
end
end
errors.none?
end
def validate_attributes!(*attributes)
valid_attributes?(*attributes) || raise(ActiveModel::ValidationError.new(self))
end
end