【问题标题】:Determine source property of DataMapper validation errors确定 DataMapper 验证错误的源属性
【发布时间】:2012-04-16 08:55:03
【问题描述】:

我对 Ruby、Sinatra 和 DataMapper 比较陌生,但对 DataMapper 验证错误有疑问。

我知道您可以通过执行以下操作来查看使用 DataMapper 将新行保存到数据库时发生的任何错误:

user = User.new username: 'bradleygriffith', password: 'not_my_password'
if user.save
  #success!
else
  user.errors.each do |error|
    puts error
  end
end

我希望能够确定错误发生在哪个属性上。例如,通过这种方式,我可以在注册表中的相应字段旁边放置错误消息。也就是说,我想知道注册人在显示错误消息之前输入了一个无效的用户名,以便我可以将消息放在用户名字段旁边。

这可能吗?

【问题讨论】:

    标签: ruby sinatra datamapper ruby-datamapper


    【解决方案1】:

    模型类的errors 属性中的所有项目都是DataMapper::Validation::Violation 的实例,它有一个名为attribute_name 的属性。

    查看line 60 中的datamapper source

    #...
    def attribute_name
      if @attribute_name
        @attribute_name
      elsif rule
        rule.attribute_name
      end
    end
    #...
    

    这意味着你可以做到这一点

    user = User.new username: 'bradleygriffith', password: 'not_my_password'
     if user.save
        #success!
     else
        user.errors.each do |error|
            #print the name of the invalid attribute
            puts error.attribute_name
        end
     end
    

    这可能不明显的原因是因为Violation#to_s 方法别名为messageputs 将调用#to_s 传递给它的任何对象,所以当你调用@987654333 @ 它实际上打印了error.message

    【讨论】:

    • 我得到:“NoMethodError at /join. undefined method 'attribute_name' for ["Username is already taken"]:Array" 有什么想法吗?
    • hmm,执行此操作puts error[0].class.name 以查看数组中的对象类型。它看起来像一个字符串,但它可能会欺骗我们。如果你解决了这个问题,请告诉我。
    【解决方案2】:

    errors 对象是 DataMapper::Validations::ValidationErrors 的一个实例,它有一个 on 方法,该方法将返回一个数组,其中包含作为参数传递的属性的所有验证错误消息,如果没有则返回 nil错误。 (看起来那些文档实际上与实现不匹配)。

    user = User.new username: 'joe', :age => 40
    
    if user.save
      #success!
    else
      puts "Username: #{user.username} #{user.errors.on(:username)}"
      puts "Age: #{user.age} #{user.errors.on(:age)}"
    end
    

    产生(设置了合适的验证):

    Username: joe ["Username must be between 4 and 20 characters long"]
    Age: 40 
    

    【讨论】:

      【解决方案3】:

      我发现以下允许您获取特定于字段的错误:

      user.errors.keys.each do |key|
        user.errors[key].each do |error|
          puts "#{key} => #{error}"
        end
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-11
        • 2018-07-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多