Nik*_*hev 31 validation ruby-on-rails rails-activerecord
如果有办法我可以在Rails中验证单个属性?
就像是:
ac_object.valid?(attribute_name)
Run Code Online (Sandbox Code Playgroud)
我将它用于特定模型字段的AJAX验证.将这些验证移动到Javascript会使代码变得非常难看.
egz*_*gze 39
您可以在模型中实现自己的方法.像这样的东西
def valid_attribute?(attribute_name)
self.valid?
self.errors[attribute_name].blank?
end
Run Code Online (Sandbox Code Playgroud)
或者将其添加到 ActiveRecord::Base
xle*_*ras 27
有时会有非常昂贵的验证(例如需要执行数据库查询的验证).在这种情况下,您需要避免使用,valid?因为它只是比您需要的更多.
还有另一种解决方案.你可以使用的validators_on方法ActiveModel::Validations.
validators_on(*attributes)public
列出用于验证特定属性的所有验证程序.
根据您可以手动验证您想要的属性
例如,我们只是想确认title的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
Run Code Online (Sandbox Code Playgroud)
哪里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
Run Code Online (Sandbox Code Playgroud)
这将仅验证title属性而不调用任何其他验证.
p = Post.new
p.validate_title("")
p.errors.messages
#=> {:title => ["title can not be empty"]
Run Code Online (Sandbox Code Playgroud)
我并不完全相信我们应该validators_on安全使用,所以我会考虑以理智的方式处理异常validates_title.
我总结了@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
Run Code Online (Sandbox Code Playgroud)
然后,我可以在控制器中执行以下操作:
if @post.valid_attributes?(:title, :date)
render :post_preview
else
render :new
end
Run Code Online (Sandbox Code Playgroud)