2010-01-20 14 views
0

Je travaille avec un framework externe (redmine) qui a un modèle Project qui a beaucoup de EnabledModules.Redmine Plugins - Détection de l'activation et de la désactivation des modules

Les projets peuvent avoir EnabledModules « attachés » ou « enlevés » par le nom du module, comme ceci:

class Project < ActiveRecord::Base 
    ... 
    has_many :enabled_modules, :dependent => :delete_all 
    ... 
    def enabled_module_names=(module_names) 
    enabled_modules.clear 
    module_names = [] unless module_names && module_names.is_a?(Array) 
    module_names.each do |name| 
     enabled_modules << EnabledModule.new(:name => name.to_s) 
    end 
    end 
end 

Je voudrais détecter de nouveaux modules sont fixés/enlevés par callbacks sur EnabledModule, et non modifier le "code source original" si possible.

Je peux détecter « pièces jointes » comme celui-ci:

class EnabledModule < ActiveRecord::Base 
    belongs_to :project 

    after_create :module_created 

    def module_created 
    logger.log("Module attached to project #{self.project_id}") 
    end 
end 

Je pensais que before_destroy travaillerait pour détecter le transfert, mais il ne sera pas. Cela se produit parce que l'appel enabled_modules.clear sur Project.enabled_module_names=, n'invoque pas «détruire» sur les modules. Il définit simplement project_id à zéro. Donc j'ai pensé que je devrais utiliser un after_update ou before_update. Si j'utilise after_update, comment puis-je obtenir le 'project_id' précédent? Si j'utilise before_update, comment puis-je différencier les modules qui sont 'juste mis à jour' des modules dont le projet_id va être réinitialisé à 0?

Dois-je utiliser une approche totalement différente ici?

EDIT: J'ai juste found out que je pouvais obtenir les anciennes valeurs avec '_was' (c'est-à-dire self.project_was). Cependant, collection.clear ne semble pas déclencher de rappels de mise à jour. D'autres solutions?

EDIT 2: Titre modifié

Répondre

1

J'ai fini par réimplémenter la méthode des projets enabled_module_names=, y compris un fichier dans fournisseur/plugins/my_plugin/lib/mon_plugin/patches/project_patch.rb et un alias. J'ai dû inclure du code sur mon fournisseur/plugins/my_plugin/init. J'ai dû inclure du code sur mon fournisseur/plugins/my_plugin/init.fichier rb aussi:

require 'redmine' 

require 'dispatcher' 

# you can add additional lines here for patching users, memberships, etc... 
Dispatcher.to_prepare :redmine_sympa do 
    require_dependency 'project' 
    require_dependency 'enabled_module' 

    Project.send(:include, RedmineSympa::Patches::ProjectPatch) 
    EnabledModule.send(:include, RedmineSympa::Patches::EnabledModulePatch) 

end 

Redmine::Plugin.register :redmine_sympa do 
# ... usual redmine plugin init stuff 
end 

Après cela, j'ai pu détecter des suppressions sur les modules activés (via before_delete) sur mon patcher.

0

En ce qui concerne:

Si je after_update, comment puis-je obtenir le 'précédent' PROJECT_ID

Peut-être essayer project_id_was, il est fourni par ActiveRecord::Dirty

+0

Salut szelmek, merci pour votre réponse rapide, vous m'avez parlé d'ActiveRecord :: Dirty en même temps que je le cherchais. Cependant, ni after_update ni before_update ne sont déclenchés par collection.clear, donc je dois essayer quelque chose d'autre. – kikito

1

Il semble que la révision 2473 de Redmine devrait résoudre votre problème. Voir les différences ici: http://www.redmine.org/projects/redmine/repository/diff/trunk/app/models/project.rb?rev=2473&rev_to=2319

Fondamentalement, le code a été modifié de sorte que les modules supprimés soient détruits plutôt que supprimés, la différence étant que les rappels de modèle ne sont pas déclenchés pour les suppressions.

Il existe une autre correction connexe dans la révision 3036 qui semble importante (voir http://www.redmine.org/issues/4200), donc vous pourriez vouloir récupérer au moins cette version.

+0

Salut Steven, merci d'avoir répondu. Tu as raison. J'ai fini par "ré-implémenter" le enabled_module_names = sur les projets afin que les callbacks "destroy" soient appelés. Je mets ma propre solution ci-dessous. – kikito