在ActiveRecord的/ Rails的原子插入或增 [英] atomic insert or increment in ActiveRecord/Rails

查看:137
本文介绍了在ActiveRecord的/ Rails的原子插入或增的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是落实在Rails的一个柜台一个模型中的原子插入/更新的最佳方法是什么?一个很好的比喻这个问题我想解决的是一个喜欢的柜台有两个字段:

What's the best way to implement an atomic insert/update for a model with a counter in Rails? A good analogy for the problem I'm trying to solve is a "like" counter with two fields:

url   : string
count : integer

对插入,如果目前不具有匹配URL的纪录,新纪录应该用计数1创建的;否则现有记录的计数字段应递增。

起初我试过code这样的:

Initially I tried code like the following:

Like.find_or_create_by_url("http://example.com").increment!(:count)

但勿庸置疑,产生的SQL显示了 SELECT 发生在更新之外交易:

Like Load (0.4ms)  SELECT `likes`.* FROM `likes` WHERE `likes`.`url` = 'http://example.com' LIMIT 1
(0.1ms)  BEGIN
(0.2ms)  UPDATE `likes` SET `count` = 4, `updated_at` = '2013-01-17 19:41:22' WHERE `likes`.`id` = 2
(1.6ms)  COMMIT

有一个Rails的成语处理这个,还是我需要在SQL级实施这一(并因此失去了某些便利)?

Is there a Rails idiom for dealing with this, or do I need to implement this at the SQL level (and thus lose some portability)?

推荐答案

我不知道有任何ActiveRecord的方法implemts原子增量在一个查询的。你自己的答案是只要你能得到。

I am not aware of any ActiveRecord method that implemts atomic increments in a single query. Your own answer is a far as you can get.

所以,您的问题可能没有解决的使用ActiveRecord的。请记住:ActiveRecord的只是一个映射器简化了一些东西,而复杂的人。有些问题通过简单的SQL查询到数据库中只可解。你将失去一些便携性。下面的例子将工作在MySQL的,但据我所知,没有对SQLlite等。

So your problem may not be solvable using ActiveRecord. Remember: ActiveRecord is just a mapper to simplify some things, while complicating others. Some problems just solvable by plain SQL queries to the database. You will loose some portability. The example below will work in MySQL, but as far as I know, not on SQLlite and others.

 quoted_url = ActiveRecord::Base.connection.quote(@your_url_here)
::ActiveRecord::Base.connection.execute("INSERT INTO likes SET `count` = 1, url = \"#{quoted_url}\" ON DUPLICATE KEY UPDATE count = count+1;");

这篇关于在ActiveRecord的/ Rails的原子插入或增的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆