2010-09-17 9 views
7

Ich habe eine Rails-Anwendung erstellt, die Buchhaltungsfunktionen ausführt. Als Teil davon habe ich ein Modell mit dem Klassennamen Transaction. So weit, so gut, ich habe diese Funktionalität für einen Monat oder so gebaut, und alles funktioniert wie erwartet.Auflösen eines Klassennamenskonflikts in einer Rails-Anwendung

Bis jetzt ...

Ich habe entdeckt, nur einige ältere Berichtsfunktionen, die vor Monaten entwickelt wurde die Ruport Bibliothek hat aufgehört zu arbeiten. Es scheint, dass Ruport beim Erzeugen von PDFs eine Bibliothek benötigt, die auch eine Klasse/Modul mit dem Namen Transaction hat.

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

... 

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

Also, ich bin auf der Suche nach einer schnellen Lösung hier. Eines, das hoffentlich nicht mein Transaction Modell umwandelt und den Code der letzten paar Wochen refactoring.

Wir freuen uns auf ein paar kluge Vorschläge :)

Antwort

7

Ich glaube, das Problem ist, bis auf Ruport die PDF erfordert :: Writer-Juwel, das seinerseits das Transaction :: Simple-Juwel benötigt, das das Modul Transaction definiert.

Es gibt sicherlich eine # transaction-Methode in ActiveRecord, aber ich glaube nicht, dass es ein Transaction-Modul oder eine Klasse in Rails gibt. Ich bin froh, dass ich darüber korrigiert werde.

Namespaces sind normalerweise die beste Methode, um Namenskonflikte wie diese zu vermeiden. Z.B.

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

Namespacing ActiveRecord-Modelle können jedoch andere Probleme verursachen.

So zeitaufwendig es auch sein mag, die Umbenennung Ihres Transaktionsmodells ist möglicherweise die beste Wahl.

Sie können Ihre vorhandene Transaktionsdatenbanktabelle weiterhin beibehalten, wenn Sie möchten, damit Ihre Migrationen nicht geändert werden müssen, indem Sie self.table_name = "transactions" in Ihr Modell einfügen.

Ihre Assoziationen mit anderen Modellen können auch als "Transaktion (en)" bezeichnet werden, indem Sie den Klassennamen in Ihrem Assoziationsaufruf angeben. Z.B.

class User < ActiveRecord::Base 

    has_many :transactions, :class_name => "AccountTransaction" 

end 

Diese zwei Vorschläge können oder nicht sparen Sie einige Zeit.

+0

Danke. Ich habe Ihre Antwort auf die angenommene Antwort geändert, da sie genauer das spezifische Problem beschreibt, das ich habe - obwohl Yannis, Antwort auch korrekt ist! Am Ende habe ich mein Modell, meine Datenbanktabelle und alle Zuordnungen umbenannt, indem ich alte-skool-Suchen und -Ersetzungen verwendete;) – aaronrussell

+0

In der neueren Version von Rails ist 'set_table_name' nur 'self.table_name =', siehe http://api.rubyonrails.org/classes/ActiveRecord/ModelSchema/ClassMethods.html#method-i-table_name-3D –

0

Ihr Problem aus der Tatsache kommen, dass Transaktion auch in Rails ein reserviertes Wort ist ...

+0

Ist es das? Verdammt! Aber danke für die Information ... – aaronrussell

+4

Rails ist nur eine Ruby-Bibliothek, es kann keine Schlüsselwörter zur Ruby-Sprache hinzufügen. –

+1

Es könnte nur eine Bibliothek sein, aber es kann der Benennung von Dingen, die es verwenden, Grenzen auferlegen (auch wenn diese von der Sprache nicht zwingend durchgesetzt werden).Sehen Sie sich die Probleme an, die Sie beim Verwenden des Spaltennamens 'type' bekommen ... –

13

Bereits beantwortet und alt, aber ich kam hier mit dem gleichen Problem, aber löste es auf eine andere Art und Weise.

Ich habe zwei Modelle namens Pull und Query. Der Versuch, innerhalb einer Pull-Methode auf Query.some_static_method() zu verweisen, führte zur Auflösung der Abfrage auf ActiveRecord::AttributeMethods::Query:Module.

es wurde gelöst durch den leeren Namensraum vor ihm mit ::Query.some_static_method() setzen

+0

Schöne Antwort, kannte den leeren Namensraum nicht! –

+0

Elegante Lösung. Können Sie genau erklären, warum/wie es funktioniert? – cph2117

+0

@ cph2117, alles, was wirklich tut, ist explizit darüber, welcher Namespace "Query" finden soll. – hometoast

Verwandte Themen