2017-04-05 1 views
0

Ceci est mon comment mon modèle ressemble à:RoR - modèle after_create clé étrangère est nulle

class MyModel < ActiveRecord::Base 

    belongs_to :parent_model 

    after_create :create_model 

    after_update :update_model 

    def create_model 
    # some code goes here 
    ...... 
    puts "Parent id: " + self.parent_model_id.to_s 
    #parent_model_id is nil here 
    end 

    def update_model 
    puts "Parent id: " + self.parent_model_id.to_s 
    #parent_model_id is as it should be 
    end 

end 

Je veux accéder à la valeur de sa clé étrangère à la fin de after_create mais il est nil là et il va à Exception. Même si les autres champs ne sont pas nil (les propres champs du modèle), la clé étrangère est.

Si j'essaie d'accéder à la clé étrangère au after_update, c'est OK. Que se passe-t-il ici?

+2

Première chose que vous devez changer les noms des méthodes –

+0

@DeepakMahakale Merci, je l'ai fait, mais il n'a pas résolu le problème. –

Répondre

0

Rails encapsule chaque changement de base de données dans une transaction et les callbacks after_create et after_update s'exécutent dans cette transaction. Cela signifie que lorsque vous appelez une méthode after_create, les modifications de la base de données ne sont pas effectuées et vous obtenez un ID nul pour parent_model_id.

Un rappel after_update appelé lorsque vous avez créé un enregistrement et que vous y apportez des modifications. Dans ce cas, parent_model_id sera toujours disponible et vous n'obtiendrez pas d'erreur.

Vous pouvez utiliser un autre rappel, after_commit. Ce rappel est appelé lorsque toutes les modifications de la base de données sont effectuées. Il sera appelé dans les deux cas, créant un nouvel enregistrement et mettant à jour l'enregistrement existant.

+0

vous pouvez vérifier les valeurs de soi en ajoutant 'binding.pry' dans les deux méthodes et vérifier la différence – bunty

+0

Merci, je le comprends. Est-il possible de faire une distinction dans 'after_commit' entre' after_create' et 'after_update'? –

+0

vous pouvez utiliser l'option ': on' avec rappel, par exemple' after_commit: create_model, on: [: create] 'ou utiliser aliase' after_create_commit' – bunty