2

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

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

这可能吗?

4

3 回答 3

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 
于 2012-04-03T20:08:30.090 回答
1

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

查看数据映射器源第 60 行

#...
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方法被别名为message并将puts调用#to_s传递给它的任何对象,因此当您调用puts error它时实际上会打印error.message.

于 2012-04-02T18:05:23.727 回答
1

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

user.errors.keys.each do |key|
  user.errors[key].each do |error|
    puts "#{key} => #{error}"
  end
end
于 2014-02-26T21:40:14.530 回答