【发布时间】:2013-12-09 17:39:13
【问题描述】:
我有一个模型,它使用回调来规范化它的一个参数,并且该参数是模型唯一键的一部分。但是当使用MyModel.find_or_create_by() 时,回调不会在“查找”阶段发挥作用,只有“创建”阶段才会发挥作用,为时已晚。
这样做有没有优雅的模式?一个人为的例子:
class CreateMyModels < ActiveRecord::Migration
def change
create_table :my_models do |t|
t.float :value
end
add_index :my_models, :value, :unique => true
end
end
class MyModel < ActiveRecord::Base
before_save :quantize_value
private
def quantize_value
self.value = ((self.value || 0.0) * 256.0).round / 256.0
end
end
让我们试试吧:
>> a = MyModel.find_or_create_by(:value => 0.501)
=> #<MyModel id: 1, value: 0.5>
到目前为止,一切都很好。如果我们 find_or_create_by 另一个其值接近但不等于现有记录,我们希望它找到现有记录。但相反,我们得到:
>> b = MyModel.find_or_create_by(:value => 0.5001)
PG::UniqueViolation: ERROR: duplicate key value violates unique constraint ...
我想要 - 从概念上讲 - 让 quantize_value 方法在运行查找之前运行。
当然,我已经编写了一个自定义构造函数,在运行查找之前应用 quantize_value 方法。但是,如果经验教会了我什么,那就是 Rails 的开发人员已经编写了我认为需要编写的代码,而创建我自己的构造函数就是复制他们的工作! :)
【问题讨论】:
标签: ruby-on-rails activerecord callback ruby-on-rails-4