0

我是 Ruby on Rails 的新手,这是我的第一个项目。我不太了解,但我有一个表,它有一个唯一的索引。例如,对于 User,唯一索引是电子邮件,所以我不能添加两个具有相同电子邮件的用户。

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

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

4

2 回答 2

3

Rails 方式(不是书本)

Rails 做到这一点的方法是在数据到达数据库之前对其进行验证。这是使用验证完成的。

在您正在寻找的特定情况下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={}>
于 2013-10-08T07:25:51.943 回答
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

更多信息请通过此链接单击此处

于 2013-10-08T14:19:18.367 回答