2009-05-20 7 views
3

Ich habe eine einfache has_one/gehört_to Beziehung zwischen zwei Modellen.Erstellen Sie unauffällig einen Datensatz für eine Zuordnung, wenn Sie versuchen, zuzugreifen?

Dies ist eine neue Zuordnung in meiner Anwendung, daher gibt es viele Datensätze, die noch nicht den zugehörigen Datensatz erstellt haben.

Während meiner gesamten Anwendung gehe ich davon aus, dass das Modell die Assoziation hat und ich auf seine Attribute und Methoden zugreife. Da die Verknüpfung jedoch nicht vorhanden ist, sind viele Fehler aufgetreten.

Was ich gerne tun würde ist unauffällig den zugehörigen Datensatz im laufenden Betrieb zu erstellen, wenn es zum ersten Mal durch eine seiner Methoden und Attribute zugreifen. Es spielt keine Rolle, dass Daten in den Datensätzen enthalten sind, ich brauche sie einfach, damit die Methoden, die ich anrufe, die Daten aufbauen können.

Bearbeiten: Ich möchte nicht überprüfen und erstellen Sie den Datensatz auf allen Instanzen, wo ich versuche, auf die Beziehung zugreifen, so dass dies auf dem Modell selbst und nicht in meinen Controllern durchgeführt werden muss .

Irgendwelche Gedanken?

Danke!

Antwort

1

Hier ist, was wir den Trick mit dem tat endete. Ich habe es nicht geschrieben (ein Kollege hat es getan), aber es besteht die zuvor nicht bestandenen Tests, die ich für diesen Fall geschrieben habe.

def stats_with_create 
    stats_without_create || create_stats 
end 
alias_method_chain :stats, :create 
0

In der Steuerung, könnten Sie so etwas wie dies in der show Methode (ungetestet, setzen aber es sollte Ihnen eine Idee geben:

@thing = Thing.find params[:id] 
if @thing.other_thing.nil? 
    @thing.other_thing = OtherThing.new.save! 
    @thing.save! 
end 

Das ist nicht ideal, und man konnte es wahrscheinlich bereinigen ein Durch das Einfügen einer Methode in das Thing-Modell, die nach dem zugehörigen Modell sucht und es erstellt, anstatt es in den Controller zu schreiben.

Eine andere Option wäre, einen neuen Accessor zu erstellen, mit dem Sie auf other_thing zugreifen und ihn als erstellen erforderlich

Die richtige Lösung ist jedoch wahrscheinlich, Ihre Daten entweder in einer Migration oder direkt zu korrigieren, indem Sie die entsprechenden Modelle ordnungsgemäß erstellen.

+0

Richtig, das ist nicht ideal.Ich müsste das tun, wo immer es ist. Deshalb muss ich es im Modell selbst oder in der Beziehung machen lassen. – mwilliams

+0

Ich habe ein wenig mehr Details für Alternativen hinzugefügt. –

0

Die direkte Antwort besteht darin, die Methode für die Beziehung zu überschreiben. Wenn es aufgerufen wird, prüft es, ob der Datensatz existiert und erzeugt es, wenn dies nicht der Fall ist.

Ich würde jedoch empfehlen, dass Sie eine Migration verwenden, um alle Datensätze im Voraus zu erstellen.

0

Ich habe diese Art der Sache vor, aber nicht auf der Modellebene gemacht. Ich habe es auf der Controller-Ebene mit einem before_filter gemacht, das vor allen Methoden lief, die auf die Modellassoziation zugreifen mussten, die noch nicht existierte oder noch nicht existierte.

Ich habe gerade festgestellt, dass es die Callbacks after_find und after_initialize gibt, die Sie im Modell verwenden können.

Sie könnten bleiben:

def after_initialize 
    association.build if association.nil? 
end 

in Ihrem Modell, und es sollte Ihre Probleme .. (Disclaimer: ungetestet von mir) lösen :)