回调除了运行您告诉它们运行的代码之外没有其他任何作用。如果你想阻止某些事情的执行,你有两个选择,使用验证或引发错误。
在您当前的代码中,您可以检查您运行的查询是否返回任何内容,如果返回则引发错误。错误将冒泡到包装保存并触发回滚的事务,然后将错误传播到您的代码中,如果您愿意,您可以在其中处理它。
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'