我是 Ruby on Rails 的新手,这是我的第一个项目。我不太了解,但我有一个表,它有一个唯一的索引。例如,对于 User,唯一索引是电子邮件,所以我不能添加两个具有相同电子邮件的用户。
但是,我想知道如何捕获这些数据库错误,以及如何将它呈现在一个好的用户消息中?
现在,我刚刚收到一个数据库错误。
我是 Ruby on Rails 的新手,这是我的第一个项目。我不太了解,但我有一个表,它有一个唯一的索引。例如,对于 User,唯一索引是电子邮件,所以我不能添加两个具有相同电子邮件的用户。
但是,我想知道如何捕获这些数据库错误,以及如何将它呈现在一个好的用户消息中?
现在,我刚刚收到一个数据库错误。
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={}>
您可以使用 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
更多信息请通过此链接单击此处。