コールバックは、実行するように指示したコードを実行する以外に何もしません。何かが実行されないようにしたい場合は、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'