2015-06-26 8 views
6

Sto usando la gemma aasm_state, insieme a sidekiq. Ecco cosa customer.rb assomiglia per la definizione di aasm_state:Il valore viene impostato anche se before_save lo imposta su nil

aasm do 
    state :closed, initial: true 
    state :open 
    state :claimed 

    event :open do 
     transitions from: :closed, to: :open 
    end 

    event :claim do 
     transitions from: [:open, :closed], to: :claimed 
    end 

    event :close do 
     transitions from: [:open, :claimed], to: :closed 
     before do 
     self.user_id = nil 
     end 
    end 
    end 

e poi ho anche in customer.rb:

def properly_close 
    if closed? && user_id 
     Rails.logger.info "Bad customer state with customer_id: #{id} at #{Time.now} and the last message was at #{messages.last.created_at}. Aasm_state_was: #{aasm_state_was}" 
     self.user_id = nil 
    end 
    end 

Ogni volta aasm_state == 'chiuso', non dovrebbe mai essere un user_id sul cliente. Tuttavia, succede ancora, frequentemente. Penso che abbia qualcosa a che fare con i lavori sidekiq in parallelo, ma non sono sicuro. Anche con i miei due modi di fare in modo user_id = nullo (nella prima di fare e in properly_close), finisce ancora in piedi sempre impostato con aasm_state == 'chiuso' & & ID_utente

Come è possibile? Come faccio a capire come sta succedendo?

+0

Possiedi * * lock_version colonna della tabella? Prova ad aggiungerlo per attivare il meccanismo di blocco ottimistico incorporato aggiungendo questa colonna. Almeno può aiutare a scoprire più accessi simultanei a quella tabella. – Anatoly

+0

Farò una prova. Tuttavia, pensando a come funziona activerecord/sidekiq, se i singoli valori di ciascun lavoro non possono mai essere aasm_state = closed && user_id non è nulla, sto cercando di capire come possa essere il problema la concorrenza. –

+0

Usi 'update_attribute' per impostare direttamente lo stato? 'update_attribute' eviterà convalide e callback. – nathanvda

risposta

4

In entrambi i casi è necessario save l'aggiornamento, cioè:

self.user_id = nil 
self.save 

O in modo più conciso (e saltare callback):

self.update_attribute :user_id, nil 
Problemi correlati