2009-10-09 5 views
0

J'ai des états qui ont beaucoup de villes (belongs_to: state) qui ont beaucoup d'entreprises (belongs_to: city). État aussi ... has_many: entreprises,: through =>: villesEnlever le: has_many quand le: belongs_to est mis à jour/détruit si le: has_many est maintenant vide

Sur mon site, tout est géré depuis la perspective Business. Quand une nouvelle entreprise est créée/mise à jour, l'état/ville est créé s'il n'existe pas déjà. Cela se passe dans un appel: before_save.

Je rencontre des problèmes lors de la suppression des États/Cités lorsqu'une entreprise est mise à jour. Si l'état/la ville dans laquelle se trouve une entreprise est modifié (encore une fois, cela se produit à partir d'un formulaire d'activité d'édition) et que l'ancien état/ville n'a plus d'entreprise, je veux le détruire. J'ai essayé de le faire dans les appels after_save mais ils sont enveloppés dans une transaction et même si j'assigne des variables aux noms de l'ancien état/ville, ils semblent être changés en nouvel état/ville au cours de la transaction. C'est fou! J'ai utilisé des appels «puts» pour imprimer les vars à certains endroits dans mon Business model et j'ai regardé les vars changer pendant une sauvegarde. C'était frustrant. Donc, en ce moment je gère cela à partir du contrôleur, mais il se sent hackish.

Voici une partie de mon code.

http://pastie.org/648832

Aussi, j'aimerais toute entrée sur la meilleure façon de structurer cette chose.

Merci

Répondre

1

Vous voulez callbacks after_destroy de détruire le côté a beaucoup d'une relation si elle en a pas.

Pour garantir ce comportement après une mise à jour, nous devons utiliser les méthodes ActiveRecord :: Dirty. Qui sont construits dans des rails à partir de 2.1. Si vous utilisez une version plus ancienne, vous aurez besoin du Dirty plugin

class Business < ActiveRecord::Base 
    ... 
    after_update :destroy_empty_city 
    after_destroy :destroy_empty_city 

    protected 
    def destroy_empty_city 
     c = city_changed? ? city_was : city 
     c.destroy if c.businesses.empty? 
    end 


end 

class City < ActiveRecord::Base 
    ... 
    after_destroy :destroy_empty_state 

    protected 
    def destroy_empty_state 
     state.destroy if state.businesses.empty? 
    end 


end 

vous pourriez avoir besoin de vérifier si city/state.businesses == [self] au lieu de city/state.businesses.empty? si vos associations sont désireux chargés. Je ne me souviens pas comment les rails traitent les associations après les avoir détruites. Je suppose que s'ils sont impatients chargés que le code ci-dessus ne fonctionnera pas et vous aurez besoin de l'autre chèque. Sinon, ça devrait aller.

+0

C'est très bien pour détruire des entreprises, mais ne traite pas les mises à jour qui est le vrai problème. – kjs3

+0

Désolé, j'ai manqué le peu de mises à jour. J'ai modifié ma réponse pour l'attraper. – EmFi

Questions connexes