2009-11-02 10 views
7

मौजूदा रिकॉर्ड पर काम करने के लिए मुझे state_machine मणि (http://github.com/pluginaweek/state_machine/) नहीं मिल रहा है (यह नए रिकॉर्ड पर सही ढंग से काम करता है)।state_machine केवल नए रिकॉर्ड के लिए काम करता है

यहाँ मेरी मॉडल है:

class Comment < ActiveRecord::Base 
    state_machine :state, :initial => :pending do 
    event :publish do 
     transition all => :published 
    end 
    end 
end 

और यहाँ एक आईआरबी सत्र कि इस मुद्दे को दर्शाता है (मैं ActiveRecord::Base.logger = Logger.new(STDOUT) किया यह पढ़ने में आसान बनाने के लिए):

>> c = Comment.new 
=> #<Comment id: nil, song_id: nil, author: nil, body: nil, created_at: nil, updated_at: nil, state: "pending"> 
>> c.state 
=> "pending" 
>> c.publish 
    Comment Create (0.6ms) INSERT INTO "comments" ("updated_at", "body", "author", "song_id", "created_at", "state") VALUES('2009-11-02 02:44:37', NULL, NULL, NULL, '2009-11-02 02:44:37', 'published') 
=> true 
>> Comment.last.state 
    Comment Load (0.4ms) SELECT * FROM "comments" ORDER BY comments.id DESC LIMIT 1 
=> "published" 
>> c = Comment.create 
    Comment Create (0.5ms) INSERT INTO "comments" ("updated_at", "body", "author", "song_id", "created_at", "state") VALUES('2009-11-02 02:44:47', NULL, NULL, NULL, '2009-11-02 02:44:47', 'pending') 
=> #<Comment id: 4, song_id: nil, author: nil, body: nil, created_at: "2009-11-02 02:44:47", updated_at: "2009-11-02 02:44:47", state: "pending"> 
>> c.publish 
=> true 
>> c.save 
=> true 
>> Comment.last.state 
    Comment Load (0.4ms) SELECT * FROM "comments" ORDER BY comments.id DESC LIMIT 1 
=> "pending" 

Ie, सब कुछ ठीक काम करता है जब मैं publish एक सहेजी गई टिप्पणी, लेकिन जब मैं एक टिप्पणी प्रकाशित करने का प्रयास करता हूं जो पहले ही सहेजा गया है, कुछ नहीं होता है।

एक और संपादन: शायद समस्या की जड़?

=> true 
>> a = Comment.last 
    Comment Load (1.3ms) SELECT * FROM "comments" ORDER BY comments.id DESC LIMIT 1 
=> #<Comment id: 3, song_id: nil, author: nil, body: nil, created_at: "2009-11-03 03:03:54", updated_at: "2009-11-03 03:03:54", state: "pending"> 
>> a.state 
=> "pending" 
>> a.publish 
=> true 
>> a.state 
=> "published" 
>> a.state_changed? 
=> false 

अर्थात, और भले ही राज्य वास्तव में बदल गया है, state_changed? झूठे लौट रहा है और इसलिए रेल इसी डेटाबेस पंक्ति अपडेट नहीं होगा जब मैं save कहते हैं।

यह काम करता है जब मैं आंशिक अपडेट बंद है, लेकिन नहीं है जब मैं state_will_change! कोशिश:

>> Comment.partial_updates = false 
=> false 
>> c = Comment.create 
    Comment Create (0.5ms) INSERT INTO "comments" ("updated_at", "body", "author", "song_id", "created_at", "state") VALUES('2009-11-07 05:06:49', NULL, NULL, NULL, '2009-11-07 05:06:49', 'pending') 
=> #<Comment id: 7, song_id: nil, author: nil, body: nil, created_at: "2009-11-07 05:06:49", updated_at: "2009-11-07 05:06:49", state: "pending"> 
>> c.publish 
    Comment Update (0.9ms) UPDATE "comments" SET "created_at" = '2009-11-07 05:06:49', "author" = NULL, "state" = 'published', "body" = NULL, "song_id" = NULL, "updated_at" = '2009-11-07 05:06:53' WHERE "id" = 7 
=> true 
>> Comment.last.state 
    Comment Load (0.5ms) SELECT * FROM "comments" ORDER BY comments.id DESC LIMIT 1 
=> "published" 
>> Comment.partial_updates = true 
=> true 
>> c = Comment.create 
    Comment Create (0.8ms) INSERT INTO "comments" ("updated_at", "body", "author", "song_id", "created_at", "state") VALUES('2009-11-07 05:07:21', NULL, NULL, NULL, '2009-11-07 05:07:21', 'pending') 
=> #<Comment id: 8, song_id: nil, author: nil, body: nil, created_at: "2009-11-07 05:07:21", updated_at: "2009-11-07 05:07:21", state: "pending"> 
>> c.state_will_change! 
=> "pending" 
>> c.publish 
=> true 
>> c.save 
=> true 
>> Comment.last.state 
    Comment Load (0.5ms) SELECT * FROM "comments" ORDER BY comments.id DESC LIMIT 1 
=> "pending" 

संपादित करें:

अधिक weirdness:

>> a = Comment.last 
    Comment Load (1.2ms) SELECT * FROM "comments" ORDER BY comments.id DESC LIMIT 1 
=> #<Comment id: 5, song_id: nil, author: nil, body: nil, created_at: "2009-11-02 06:33:19", updated_at: "2009-11-02 06:33:19", state: "pending"> 
>> a.state 
=> "pending" 
>> a.publish 
=> true 
>> a.state 
=> "published" 
>> a.save 
=> true 
>> a.id 
=> 5 
>> Comment.find(5).state 
    Comment Load (0.3ms) SELECT * FROM "comments" WHERE ("comments"."id" = 5) 
=> "pending" 

से तुलना करें:

!
>> a = Comment.last 
    Comment Load (0.3ms) SELECT * FROM "comments" ORDER BY comments.id DESC LIMIT 1 
=> #<Comment id: 5, song_id: nil, author: nil, body: nil, created_at: "2009-11-02 06:33:19", updated_at: "2009-11-02 06:33:19", state: "pending"> 
>> a.state = "published" 
=> "published" 
>> a.save 
    Comment Update (0.6ms) UPDATE "comments" SET "state" = 'published', "updated_at" = '2009-11-02 08:29:34' WHERE "id" = 5 
=> true 
>> a.id 
=> 5 
>> Comment.find(5).state 
    Comment Load (0.4ms) SELECT * FROM "comments" WHERE ("comments"."id" = 5) 
=> "published" 
+6

गंभीरता से राज्य, यह मुझे पागल गाड़ी चला रहा है (यहां तक ​​कि मेरी विशेष प्रोग्रामिंग टोपी (http://img4.imageshack.us/img4/9105/photo2gw.jpg) बेकार है) –

+0

: टोपी के लिए डी +1! वैसे भी, किसी भी कारण से आप अब रेल राज्य मशीन में निर्मित नहीं कर रहे हैं? http://blog.envylabs.com/2009/08/the-rails-state-machine/ –

+0

क्या यह अभी तक बाहर है? ('ActiveRecord :: StateMachine' मेरे लिए रेल 2.3.4 में विफल रहता है) –

उत्तर

1

आप के साथ प्रकाशित ** ** बजाय

+0

'प्रकाशित करें' और 'प्रकाशित करें!' उपरोक्त उदाहरणों में समान प्रभाव है (argh!) –

0

प्रकाशित फिर, अपने प्रश्न का कोई वास्तविक जवाब नहीं अपने राज्य संक्रमण पुन: प्रयास करें कर सकते हैं, लेकिन यहाँ मैं अपने सत्र अनुकरण करने की कोशिश की:

>> c = Comment.new 
=> #<Comment id: nil, body: nil, created_at: nil, updated_at: nil, state: "pending"> 
>> c.state 
=> "pending" 
>> c.publish 
=> true 
>> Comment.last.state 
=> "published" 
>> c = Comment.create 
=> #<Comment id: 4, body: nil, created_at: "2009-11-05 07:12:53", updated_at: "2009-11-05 07:12:53", state: "pending"> 
>> c.publish 
=> true 
>> c.save 
=> true 
>> Comment.last.state 
=> "published" 

जैसा कि आप देख सकते हैं, यह मेरे लिए अपेक्षित काम करता है। इसे दो बार जांच लिया। (मैंने बॉडी और स्टेट एट्रिब्यूट्स के साथ एक मॉडल बनाया है और इसमें अपना कोड डाला है।)

1

कुछ भी उपयोगी नहीं है, लेकिन मैं बस इतना कहना चाहता था कि मैं इस त्रुटि के साथ भी संघर्ष कर रहा हूं, मेरे पूरे एप्लिकेशन में कई राज्य_माचिन में । और मैं एएएसएम पर स्विच नहीं कर सकता, क्योंकि मुझे एक ही मॉडल में एक से अधिक राज्य_माचिन की आवश्यकता है ... तो निराशाजनक!

वैसे भी, आप अकेले नहीं हैं, इसे निश्चित रूप से अभी भी एक समाधान की आवश्यकता है।

1

क्या यह अभी भी आंशिक अपडेट बंद होने के साथ होता है? Comment.partial_updates = false

यदि ऐसा है, तो हम जानते हैं कि समस्या गंदे वस्तुओं की पहचान के साथ है। c.publish

+0

यही वह है जो मैं सोच रहा था कि संभावित अपराधी चूंकि आपका अपडेट उस कॉलम को नहीं भेज रहा है। –

+0

अब हम बात कर रहे हैं! यह तब काम करता है जब मैं 'Comment.partial_updates = false' करता हूं, लेकिन जब मैं' c.state_will_change करता हूं! '(http://pastie.org देखें/687584 जो मैंने किया था) दुर्भाग्य से इस मॉडल में कुछ बड़े टेक्स्ट फ़ील्ड हैं और इसलिए मैं वर्कअराउंड के रूप में आंशिक अपडेट बंद नहीं करना चाहूंगा (हालांकि मैं काम करता हूं अगर वर्कअराउंड के रूप में मैं राज्य_विल्ल_चेंज लागू करता हूं) –

+0

'c के बाद .state_will_change! 'रन' c.changed' क्या लौटा सरणी में '" राज्य "है? –

1

पर कॉल करने से पहले आपको c.state_will_change! पर कॉल करने में सक्षम होना चाहिए, क्या मॉडल प्रारंभ होने पर सुपर कॉल करता है?

state_machine प्रलेखन यह राज्यों के लिए आवश्यक है कहते हैं प्रारंभ करने के लिए

def initialize 
    @seatbelt_on = false 
    super() # NOTE: This *must* be called, otherwise states won't get initialized 
end 
0

कोशिश दूर करने के लिए: परिभाषा से राज्य:

से: state_machine: राज्य,: प्रारंभिक =>:

कर लंबित

से state_machine: प्रारंभिक =>: लंबित

2

मैं उसी जारीकर्ता पर आया ई 3 साल बाद यह अन्य लोगों के समय को बचाने के लिए यहां जवाब देने लायक है।

आपको अपनी तालिका में 'राज्य' नामक कॉलम रखना होगा, इसलिए state_machine राज्य को लगातार बनाए रखने में सक्षम होगा।

बस अपने प्रवास के लिए इसे जोड़ने - t.string:

संबंधित मुद्दे