确定DataMapper验证错误的源属性

时间:2012-04-02 17:18:00

标签: ruby sinatra datamapper ruby-datamapper

我对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

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

这可能吗?

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

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

查看line 60datamapper 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传递给它,所以当你致电puts error时,它实际上会打印error.message

答案 2 :(得分:1)

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

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