2

これは私のモデルにあるものです。重複するレコードをチェックしたいのですが、連絡先はジョブごとに一意であるため、フィールドに一意のインデックスを使用できません)次のコードを使用してこれを行うことはできません。私はそれを間違っていますか?どんな助けでも大歓迎です。ありがとう!

before_save :check_for_duplicates?

def check_for_duplicates?
  JobsPeople.find(:all, :conditions => ["job_id = ? and contact_id = ?", self.job_id, self.contact_id])
end
4

2 に答える 2

7

私はこれがあなたが望むことをするべきだと信じています

class JobsPeople
  validates_uniqueness_of :contact_id, scope: :job_id
end
于 2013-02-18T19:41:24.177 に答える
7

コールバックは、実行するように指示したコードを実行する以外に何もしません。何かが実行されないようにしたい場合は、2つのオプションがあり、検証を使用するか、エラーを発生させます。

現在のコードでは、実行したクエリが何かを返すかどうかを確認し、返す場合はエラーを発生させることができます。エラーは、保存をラップしているトランザクションにバブルアップしてロールバックをトリガーし、必要に応じて処理できるコードにエラーを伝播します。

before_save :check_for_duplicates?

def check_for_duplicates?
  if JobsPeople.find(:all, :conditions => ["job_id = ? and contact_id = ?", self.job_id, self.contact_id]).any?
    raise 'some error'
  end
end

この状況を処理する組み込みの一意性バリデーターはすでに存在しますが

validates :job_id, :uniquness => {:scope => :contact_id, :message => 'must be unique per contact}

もちろん、潜在的な競合状態が存在する可能性があるため、これはデータベース内の複合一意インデックスでバックアップする必要があります。その可能性は、アプリケーションの動作に大きく依存します。

# in a migration

add_index :table_name, [:job_id, :contact_id], :unique => true, :name => 'index_job_id_and_contact_id_on_table_name'
于 2013-02-18T19:46:00.423 に答える