Ruby on Rails は初めてで、これが最初のプロジェクトです。よくわかりませんが、一意のインデックスを持つテーブルがあります。たとえば、ユーザーの場合、一意のインデックスは電子メールであるため、同じ電子メールで 2 人のユーザーを追加することはできません。
しかし、これらのデータベース エラーを検出する方法と、適切なユーザー メッセージで表示するにはどうすればよいかを知りたいです。
さて、データベースエラーが発生しました。
Ruby on Rails は初めてで、これが最初のプロジェクトです。よくわかりませんが、一意のインデックスを持つテーブルがあります。たとえば、ユーザーの場合、一意のインデックスは電子メールであるため、同じ電子メールで 2 人のユーザーを追加することはできません。
しかし、これらのデータベース エラーを検出する方法と、適切なユーザー メッセージで表示するにはどうすればよいかを知りたいです。
さて、データベースエラーが発生しました。
これを行う 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]}>
これは機能し、私の予備テストでは明らかに壊れているものは見つからなかったので、実際には実行可能な解決策かもしれません. ただし、1 つの注意点として、検証によって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
詳細情報 こちらのリンクをクリックしてください。