Ruby on rails Rails ActiveRecord:验证单个属性

Ruby on rails Rails ActiveRecord:验证单个属性,ruby-on-rails,validation,rails-activerecord,Ruby On Rails,Validation,Rails Activerecord,是否有一种方法可以验证Rails中的单个属性 比如: ac_object.valid?(attribute_name) 我将使用它对特定模型字段进行AJAX验证。将这些验证移到Javascript会使代码变得非常难看。您可以在模型中实现自己的方法。像这样的 def valid_attribute?(attribute_name) self.valid? self.errors[attribute_name].blank? end 或者将其添加到ActiveRecord::Base有

是否有一种方法可以验证Rails中的单个属性

比如:

ac_object.valid?(attribute_name)


我将使用它对特定模型字段进行AJAX验证。将这些验证移到Javascript会使代码变得非常难看。

您可以在模型中实现自己的方法。像这样的

def valid_attribute?(attribute_name)
  self.valid?
  self.errors[attribute_name].blank?
end

或者将其添加到
ActiveRecord::Base

有时会有非常昂贵的验证(例如,需要执行数据库查询的验证)。在这种情况下,您需要避免使用
valid?
,因为它所做的远远超出您的需要

有另一种解决办法。您可以使用
ActiveModel::Validations
的方法

(*属性)公共上的验证程序

列出用于验证特定项目的所有验证器 属性

根据该属性,您可以手动验证所需的属性

e、 g.我们只想验证
帖子
标题

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
它将只验证title属性,而不调用任何其他验证

p = Post.new
p.validate_title("")
p.errors.messages
#=> {:title => ["title can not be empty"]
笔记

我不完全相信我们应该在安全地使用<代码> ValueStAs>,因此我将考虑在代码< >验证> StaseTe> 中以一种明智的方式处理异常。

< P>我在@ XLMeBRAS的答案上建立了它,并将此方法添加到我的<代码>应用程序记录< /代码>:

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

基于@coreyward的答案,我还添加了一个
validate\u属性方法:

class ApplicationRecord
事实上,如果使用某些表单生成器,这种方法可能会有问题。例如,您可能会开始在尚未输入的字段上显示错误。可以运行valid?并清除所有不在相关属性中的错误。这在某些情况下可能会起作用,但事实恰恰相反:它在后台验证所有内容。对于给定的用例来说,这是一种相当糟糕的做法,因为它将为每个属性验证整个对象。我可以在controller中使用此方法吗?使用
self.class.validators\u on
并将属性名称作为参数使其更易于重用。存在一个错误:
错误。无?
可能引用其他错误如果以前只关心布尔标志而不是实际错误,可以考虑在循环中返回如下:<代码>返回false,除非是自。错误[Atg],BLUT/<代码>。我认为<代码> [属性] < /代码>比<代码>发送(属性)好得多。
但这只是个人偏好。您也可以将其提取到关注点,而不是将其包含在父类中(同样,首选项)。@thismydesign如果您希望它仅返回指定列的状态(仅对指定列运行验证),我建议在调用
none?
errors.slice(*attributes).none?
之前切片
errors
。这不是ActiveModel::Validations处理问题的方式。//无论如何,使用
[]访问属性
与使用
send
不同。后者将调用访问器方法,这是您想要的99/100。此外,短路意味着并非所有错误都可用于视图渲染。这可能不可取。
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