如何以一种很好的方式呈现postgres错误?

时间:2013-10-08 01:43:58

标签: ruby-on-rails ruby ruby-on-rails-3 postgresql

我是Ruby on Rails的新手,这是我的第一个项目。我真的不知道,但我有一个表有一个独特的索引。例如,对于User,唯一索引是电子邮件,因此我无法使用相同的电子邮件添加两个用户。

但是,我想知道如何捕获这些数据库错误,以及如何在一个好的用户消息中显示它?

现在,我刚收到数据库错误。

2 个答案:

答案 0 :(得分:3)

Rails方式(不是书)

Rails的方法是在数据到达数据库之前验证数据。这是使用validations完成的。

在您的具体情况下,您正在寻找validates_uniqueness_of,可以像

一样使用
class YourModel
  validates_uniqueness_of :email
end

这足以确保在大多数情况下不会触发唯一约束。

捕获数据库错误

现在,如果你真的想要捕获数据库错误,那确实是可能的,但也许不是最佳的。

如果您创建自己的save方法,我们可以添加选项以捕获数据库异常,然后它们冒泡到控制器:

class User < ActiveRecord::Base
  def save(*args)
    super
  rescue ActiveRecord::RecordNotUnique
    errors[:base] << :taken
    false
  end
end

ActiveRecord::RecordNotUnique是ActiveRecord违反唯一约束时引发的异常。有了这个,我们得到以下结果:

>> u = User.new(:name => "Bob")
=> #<User id: nil, name: "Bob", created_at: nil, updated_at: nil>
>> u.save
=> false
>> u.errors
=> #<ActiveModel::Errors:0x007faa06569458 @base=#<User id: nil, name: "Bob", created_at: "2013-10-10 07:59:02", updated_at: "2013-10-10 07:59:02">, @messages={:base=>[:taken]}>

这是有效的,我的初步测试没有发现任何明显损坏,所以它实际上可能是一个可行的解决方案。但需要注意的是,验证将如何破坏errors数组:

>> u.valid?
=> true
>> u.errors
=> #<ActiveModel::Errors:0x007faa065a5368 @base=#<User id: nil, name: "Bob", created_at: "2013-10-10 08:08:36", updated_at: "2013-10-10 08:08:36">, @messages={}>

答案 1 :(得分:0)

您可以使用Rails默认验证,如

 class Person < ActiveRecord::Base
  validates :name, presence: true # you can give multiple field name like  validates :name,:email ..
  validates :name, uniqueness: true
 end

  >> p = Person.new
  #=> #<Person id: nil, name: nil>
  p.errors.messages
  #=> {}

  >> p.valid?
  #=> false
  >> p.errors.messages
  #=> {name:["can't be blank"]}

  >> p = Person.create
  #=> #<Person id: nil, name: nil>
  >> p.errors.messages
  #=> {name:["can't be blank"]}

  >> p.save
  #=> false

  >> p.save!
  #=> ActiveRecord::RecordInvalid: Validation failed: Name can't be blank

  >> Person.create!
 #=> ActiveRecord::RecordInvalid: Validation failed: Name can't be blank

更多信息请浏览此链接click Here