2010-08-20 4 views
19

Was ich suche zu tun ist, für einige meiner Modelle eine Basisklasse haben, die einige Standardactive Verhalten hat:Rails Activerecord - ohne Tisch von einer Basisklasse erben

class Option < ActiveRecord::Base 
    has_many :products 

    def some_method 
    #stuff 
    end 

    #etc..etc.. 
end 

class ColorOption < Option 
    #stuff... 
end 


class FabricOption < Option 
    #stuff... 
end 

Allerdings möchte ich ColorOption und FabricOption für jede in ihren eigenen Tabellen. Ich möchte STI NICHT verwenden oder eine Tabelle für die Basisklasse "Option" haben. Die einzige Möglichkeit, dies zu erreichen, ist eine Metaprogrammierungszauberei, die keine Vererbung darstellt. Aber ich fragte mich, ob es eine Möglichkeit gab, AR mitzuteilen, dass die Basisklasse keine Tabelle benötigt. Es ist nur da für zusätzliches Verhalten, und die anderen Unterklassen wie üblich in ihre eigene Tabelle zu setzen.

Danke, Craig

Antwort

17

Sieht aus wie ein Fall für ein Modul, das Sie umfassen.

module Option 
    def self.included(base) 
    base.has_many :products 
    end 

    # other instance methods 
end 

class ColorOption < ActiveRecord::Base 
    include Option 
    set_table_name '???' # unless ColorOption/FabricOption have same table -> move to Option module 

    #stuff... 

end 


class FabricOption < Option 
    include Option 
    set_table_name '???' # unless ColorOption/FabricOption have same table -> move to Option module 

    #stuff... 
end 

Weitere Informationen: http://mediumexposure.com/multiple-table-inheritance-active-record/

+0

Ja, ich habe das Modul versucht, aber das Modul kann die aktiven Record-Methoden wie has_many: products nicht sehen. Es sagt, dass die Methode nicht definiert ist. – fregas

+0

Wie hast du es versucht? Stephan –

+0

fregas: Stellen Sie sicher, alle Klassenmethoden Aufrufe, wie 'has_many' oder Validierungen innerhalb der' self.included' Methode Stephan hat in seinem Beispiel –

46

Was Sie wollen, ist eine abstrakte Klasse:

class Option < ActiveRecord::Base 
    self.abstract_class = true 
end 

class ColorOption < Option 
    set_table_name "color_options" 
end 

class FabricOption < Option 
    set_table_name "fabric_options" 
end 

Ich habe einige zusätzliche Informationen über STI and #abstract_class auf meinem Blog.

+0

nicht versucht, dies, aber das scheint auch zu vernünftigen – fregas

+0

muss ich den Tabellennamen festlegen, oder kann AR einfach nur schließen? – fregas

+0

Versuchen Sie es ohne. Kann nicht sagen, ob es ohne geht. –

5

Ich hatte ein ähnliches Problem, aber ich wollte auch ändern, wie AR Tabellenname für meine Modelle, dass zum Beispiel MyProject-Modell würde Tabellenname "MY_PROJECT" haben.

ich erreicht habe es durch abstrakte AR-Klasse erstellen, wie @ FFrançois sagte, und mit geerbte Methode, wo ich bin Tabellenname ändern, wie folgt aus:

class MyModel < ActiveRecord::Base 
    self.abstract_class = true 

    def self.inherited(subclass) 
    subclass.table_name = subclass.name.underscore.upcase 
    end 
end 

class MyProject < MyModel 
end 

Jetzt MyProject.table_name gibt my_project:)

Verwandte Themen