2010-09-17 31 views
7

J'ai créé une application Rails qui exécute des fonctionnalités de comptabilité. Dans le cadre de cela, j'ai un modèle avec le nom de la classe Transaction. Jusqu'ici tout va bien, j'ai construit cette fonctionnalité pour un mois ou deux, et tout fonctionne comme prévu.Résolution d'un conflit de nom de classe dans une application Rails

Jusqu'à présent ...

Je viens de découvrir certaines fonctionnalités de rapports plus qui a été développé il y a plusieurs mois en utilisant la bibliothèque Ruport a cessé de fonctionner. Il semble que Ruport, lors de la génération de fichiers PDF, nécessite une bibliothèque qui possède également un module/classe nommé Transaction.

TypeError in Admin/team reportsController#generate 
Transaction is not a module 

... 

This error occurred while loading the following files: 
    pdf/writer 
    transaction/simple 

Donc, je suis à la recherche d'une solution rapide ici. Un qui n'implique pas de renommer mon modèle Transaction et de refactoriser les dernières semaines de code.

Au plaisir de quelques suggestions intelligentes :)

Répondre

7

Je crois que la question est en baisse à Ruport PDF nécessitant :: Writer gem, qui à son tour nécessite la gemme Transaction :: Simple qui définit le module Transaction.

Il existe certainement une méthode #transaction dans ActiveRecord, mais je ne pense pas qu'il existe un module ou une classe Transaction dans Rails. Je serai heureux d'être corrigé sur celui-là.

L'attribution de noms est généralement la meilleure pratique pour éviter les conflits de nommage comme celui-ci. Par exemple.

module Account 
    class Transaction < ActiveRecord::Base 
    .... 
    end 
end 

Cependant, les modèles ActiveRecord de noms de domaine peuvent générer d'autres problèmes.

Aussi long que cela puisse paraître, renommer votre modèle de transaction peut être le meilleur choix.

Vous pouvez toujours conserver votre table de base de données de transactions existante si vous le souhaitez, afin que vos migrations n'aient pas besoin d'être modifiées, en insérant self.table_name = "transactions" dans votre modèle.

Vos associations avec d'autres modèles peuvent également être appelées "transaction (s)" en spécifiant le nom de classe dans votre appel d'association. Par exemple.

class User < ActiveRecord::Base 

    has_many :transactions, :class_name => "AccountTransaction" 

end 

Ces deux suggestions peuvent ou non vous faire gagner du temps.

+0

Merci. J'ai changé votre réponse à la réponse acceptée car elle décrit plus précisément le problème spécifique que j'ai - bien que Yannis, la réponse est également correcte! Finalement, j'ai décidé de renommer mon modèle, ma table de base de données et toutes les associations en utilisant old-skool find et replace;) – aaronrussell

+0

Dans la nouvelle version de Rails, 'set_table_name' est simplement' self.table_name = ', voir http://api.rubyonrails.org/classes/ActiveRecord/ModelSchema/ClassMethods.html#method-i-table_name-3D –

0

Votre problème peut provenir du fait que la transaction est un mot réservé dans Rails ...

+0

est-il? Zut! Mais merci de m'avoir informé ... – aaronrussell

+4

Rails est juste une bibliothèque Ruby, elle ne peut pas ajouter de mots-clés au langage Ruby. –

+1

Il peut s'agir simplement d'une bibliothèque, mais elle peut imposer des limites à la dénomination des objets qui l'utilisent (même si ceux-ci ne sont pas forcés par le langage).Regardez simplement les problèmes que vous rencontrez lorsque vous essayez d'utiliser le nom de colonne 'type' ... –

13

Déjà répondu et vieux, mais je suis venu ici avec le même problème, mais résolu d'une manière différente.

J'ai deux modèles nommés Pull et Query. En essayant de référencer Query.some_static_method() dans une méthode dans Pull, la requête s'est résolue en ActiveRecord::AttributeMethods::Query:Module.

résolu le problème en mettant l'espace de noms vide devant avec ::Query.some_static_method()

+0

Belle réponse, ne connaissait pas l'espace de noms vide! –

+0

Solution élégante. Pourriez-vous expliquer exactement pourquoi/comment cela fonctionne? – cph2117

+0

@ cph2117, tout ce que fait vraiment est d'être explicite quant à l'espace de noms à trouver 'Query'. – hometoast