2011-02-02 23 views
5

Chúng tôi có một số mã thường được nhấn trong ứng dụng của chúng tôi mà increments một cột, như vậy:Tôi có thể tăng số nguyên tử trong Rails 2.3 mà không cần phải giảm xuống SQL không?

if (r = customer.find_or_generate_reminder) 
    r.counter += 1 
    r.save! 
end 

Chúng tôi vẫn bị timeout chờ khóa, vì vậy tôi đang suy nghĩ về việc này một hoạt động nguyên tử. Naively, những gì tôi muốn làm như thế này:

if (r = customer.find_or_generate_reminder) 
    connection.excute('UPDATE customer_reminders SET counter=counter+1, updated_at=now() WHERE id = ' + r.id) 
end 

Có cách nào khác để làm điều tương tự?

Trả lời

7

Bạn có thể sử dụng phương pháp lớp increment_counter:

Customer.increment_counter :counter, customer 

Điều đó sẽ tạo ra một cái gì đó như:

UPDATE `customers` SET `counter` = COALESCE(`counter`, 0) + 1 WHERE (`customers`.`id` = 53) 

(bạn phải vượt qua hoặc một id hoặc một thể hiện của các lớp thành phương pháp này (customer) không giống như phương pháp customer.increment!(:counter) không phải là nguyên tử)

1

Tôi đã tạo một viên ngọc để làm cho hướng đối tượng này hướng đến:

https://github.com/imme5150/rails_atomic_increment

Cho phép bạn làm:

customer.atomic_increment!(:counter) 

Hãy cho tôi biết những gì bạn nghĩ.

+0

Chúng tôi đã chuyển về từ vấn đề này, nhưng điều đó trông giống như một giải pháp tốt. Cảm ơn! – Simon

0

Nếu bạn không nhớ một chút của SQL:

CustomerReminder.where(id: id).update_all('counter = counter + 1, updated_at = now()') 
Các vấn đề liên quan