我遇到的情况是我正在使用带有ActiveRecord和Rails的sqlite(同样,这是JRuby,所以我实际上使用的是jdbcsqlite适配器,以防万一)。现在,我正在尝试将一行插入表注册表中,但是只有在没有其他类似行的情况下。因此,
unless AttentionSeeker.find(:first, :conditions => {:key_id => key.id, :locale_id => l.id})
item = AttentionSeeker.new(:key_id => key.id, :locale_id => l.id)
item.save
end
这是日志中生成的输出:
CACHE (0.0ms) SELECT * FROM attention_seekers WHERE (attention_seekers.key_id = 318 AND attention_seekers.locale_id = 20)
AttentionSeeker Create (1.0ms) INSERT INTO attention_seekers (key_id, locale_id) VALUES(318, 20)
CACHE (0.0ms) SELECT * FROM attention_seekers WHERE (attention_seekers.key_id = 318 AND attention_seekers.locale_id = 20)
AttentionSeeker Create (2.0ms) INSERT INTO attention_seekers (key_id, locale_id) VALUES(318, 20)
正如您所看到的,由于某种原因,即使我插入影响它的元素,也会缓存查找。我做错了什么/如何阻止这种行为?
答案 0 :(得分:3)
我做了一些挖掘并遇到this helpful blog post,提供了更多信息here。我的解决方案(使用Mike Buckbee建议的验证 - 谢谢!):
AttentionSeeker.uncached do
item = AttentionSeeker.new(:key_id => key.id, :locale_id => l.id)
item.save
end
答案 1 :(得分:1)
不是将此代码放在您的控制器中(我猜它是在哪里),您可能需要考虑使用验证,我认为这样可以解决问题:
class AttentionSeeker < ActiveRecord::Base
validates_uniqueness_of :key_id, :scope => :locale_id
end
请注意验证规则中的“范围”选项。
如果不能尝试将查询包装在Transaction
中如果失败了,这看起来非常混乱,你可以为查询本身添加一个缓存器。像
这样的东西buster = rand(Time.now)
attention_seeker = AttentionSeeker.find(:first, :conditions => ["#{buster} = #{buster}"])
每次循环都会给你一个独特的查询。
答案 2 :(得分:0)
模式级别的唯一索引比validates_uniqueness_of更安全。
请参阅http://railswarts.blogspot.com/2007/11/validatesuniquenessof-is-broken-and.html
斯蒂芬