2011-02-02 8 views
5

हमने अपने ऐप में कुछ अक्सर प्रभावित कोड है कि एक कॉलम में जुड़ जाता है, तो तरह है:क्या मैं एसक्यूएल को छोड़ दिए बिना रेल 2.3 में परमाणु वृद्धि कर सकता हूं?

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

हम ताला प्रतीक्षा समय समाप्ति हो रही है, इसलिए मैं इस एक परमाणु आपरेशन बनाने के बारे में सोच रहा हूँ। Naively, मैं क्या करना चाहता हूं इस तरह दिखता है:

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

क्या वही काम करने का एक रूबी-वर्ल्ड तरीका है?

उत्तर

7

आप वर्ग विधि increment_counter उपयोग कर सकते हैं:

Customer.increment_counter :counter, customer 

ऐसा ही कुछ बना देंगे:

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

(आप इस विधि में या तो एक आईडी या वर्ग का एक उदाहरण पारित करने के लिए है (customer) customer.increment!(:counter) विधि के विपरीत जो परमाणु नहीं है)

1

मैंने इस ऑब्जेक्ट उन्मुख बनाने के लिए एक मणि बनाया:

https://github.com/imme5150/rails_atomic_increment

तुम क्या करने की अनुमति देता है:

customer.atomic_increment!(:counter) 

मुझे बताएं कि आप क्या सोचते हैं।

+0

हम इस समस्या से पर स्थानांतरित कर दिया है, लेकिन यह एक अच्छा समाधान की तरह दिखता है। धन्यवाद! – Simon

0

आप एसक्यूएल का एक छोटा सा कोई आपत्ति नहीं है:

CustomerReminder.where(id: id).update_all('counter = counter + 1, updated_at = now()')