2010-03-05 16 views
9

Ich versuche, einen Datensatz innerhalb einer Join-Tabelle aus der Aktion einer Schaltfläche zu erstellen. Ich würde ein Ereignismodell haben und möchte ausgewählte Ereignisse von jedem Benutzer verfolgen.Rails - Hinzufügen von Datensatz zu Join-Tabelle von Controller

Ich habe die HABTM-Beziehung benutzt, da ich wirklich keine zusätzlichen Felder brauche.

User.rb:

has_to_and_belongs_to_many :events 

Event.rb:

has_to_and_belongs_to_many :users 

Events_Users Migration:

[user_id, event_id, id=>false] 

Ich bin auf dem tatsächlichen Schaffung des Datensatzes stecken zu bleiben. Jemand hat mir geholfen, früher mit dem Hinzufügen des Datensatzes in der Konsole:

u = User.find(1) 
u.events << Event.find(1) 

Nun möchte Ich mag die Aktion als Folge auszuführen, einen Link zu klicken ... Ist das in die richtige Richtung?

def add 
    @user = User.find(session[:user_id]) 
    @event = Event.find(params[:id]) 
    if @user.events.save(params[:user][:event]) 
    flash[:notice] = 'Event was saved.' 
    end 
end 

Sollte ich hinzufügen, eine @user.events.new irgendwo und wenn ja, wo platziere ich die params von welchem ​​Benutzer und welches Ereignis?

Antwort

13

Der folgende Code sollte funktionieren (unter der Annahme, dass Sie in einem Parameter mit dem Namen id übergeben, die auf die ID eines Ereignisobjekts entspricht):

def add 
    @user = User.find(session[:user_id]) 
    @event = Event.find(params[:id]) 
    @user.events << @event 
    flash[:notice] = 'Event was saved.' 
    end 

Die Probleme, die ich in Ihrem Code zu sehen sind:

  1. Sie übergeben einen Hash an .save. Save sollte nur einen booleschen Wert annehmen, der angibt, ob Validierungen ausgeführt werden sollen, und ist standardmäßig true. Jedoch können .create und .new einen Hash von Werten akzeptieren. (.save wird nach .new verwendet).

  2. Sie laden ein Ereignis über params [: id], aber dann versuchen Sie, ein Ereignis über params [: user] [: event] zu erstellen. Was willst du machen? Erstellen oder laden? (Mein Beispiel geht von einer Last aus)

  3. Aktionen, die einen solchen Effekt haben, sollten auftreten, wenn ein Benutzer auf eine Schaltfläche klickt und ein Formular einreicht und nicht auf einen Link klickt. Dieser Code ist möglicherweise anfällig für Cross-Site-Request-Fälschung (Jemand könnte jemanden dazu bringen, auf einen Link auf einer anderen Site zu klicken, auf der diese Aktion ausgeführt wurde). Rails-Formulare sind bei korrekter Implementierung davor geschützt, da sie ein Request-Forgery-Schutz-Token verwenden.

  4. Wahrscheinlich möchten Sie den Benutzer nach dieser Aktion umleiten. Das Rendern von Seiten nach dem Ausführen von Aktionen wie diesem (statt Umleiten) wird als schlechte Übung angesehen.

+0

meinen Sie @ user.events << @ event.name ??? – ChrisWesAllen

+0

Nein. Dieser Code macht keinen Sinn, wenn ich Ihre Beschreibung des Problems richtig verstehe. – Gdeglin

+0

Danke für die Vorschläge, ich habe das "<% = link_to image_tag (" grid_heart.gif ",: border => 0),: controller => 'event',: action => 'add_event'%>" auf " 'event',: action => "add"%> "aber ich bekomme immer noch einen Fehler, dass es eine" nicht initialisierte Konstante EventController "gibt. Habe ich die Methode in den falschen Controller gesetzt? – ChrisWesAllen

3

Was Sie in der Konsole getan haben, müssen Sie in der Steuerung tun.

def add 
    @user = User.find(session[:user_id]) 
    @event = Event.find(params[:id]) 
    @user.events << @event 
    flash[:notice] = 'Event was saved.' 
end 

Die Sache hier zu beachten ist, dass die < < Betreiber für vorhandenen Datensätze des Verband sofort anhielt verursachen.

Werfen Sie einen Blick auf the ActiveRecord documentation für weitere Informationen.

0

Wenn die event_id als params übergeben wird [: id] und Sie hinzufügen, nur ein Ereignis in diesem Aufruf dann können Sie die folgenden in Ihrem Controller-Code tun:

User.find(session[:user_id]).events << Event.find(params[:id]) 
    flash[:notice] = 'Event was saved.' 

Sie keine expliziten brauchen save, um die has_many-Verknüpfung einer vorhandenen Modellinstanz zu speichern.

Szenario 1

u = User.new(..) 
u.events << Event.first 
# Now you need to call `save` in order to save the user object 
# and the events association 
u.save 

Szenario 2

u = User.first 
u.events << Event.first 
# Don't need to call `save` on `u` OR `u.events` 
+0

Ich bekomme immer noch eine nicht initialisierte Konstante EventController Jede Idee, woher es kommen könnte? – ChrisWesAllen

+0

Können Sie Ihren Controller-Code bei Pastie (http://pastie.org/) veröffentlichen und einen Link bereitstellen. –

+0

kann ich, aber das ist die einzige Methode, die ich dem event_controller hinzugefügt habe. Es gibt keinen Fehler, wenn ich die add-Methode entferne, und der Rest des Controllers wurde von einem Gerüst erzeugt, also seine ziemlich grundlegenden Sachen. Die aktuelle Methode sieht aus wie ... def \t \t @user = User.find (session [: user_id]) hinzufügen \t \t @Event = Event.find (params [: id]) \t \t @user. Ereignisse << @Event \t \t flash [: Nachricht] = 'Das Ereignis wurde gespeichert.' \t Ende – ChrisWesAllen

Verwandte Themen