2016-07-11 12 views
0

Ich versuche, mehrere Datenbankeinträge mit nur einer JSON-Anfrage zu erstellen. Jeder Eintrag besteht nur aus zwei Werten, einem Typ (der Aktion) und einer Zeit (wenn die Aktion stattfand). Um mehrere davon in eine Anfrage zu bekommen, verwende ich ein JSON-Array.Wie behandelt man eine JSON Array POST Anfrage mit Rails?

Dies ist, was Aktion eröffne mein in die Steuerung wie folgt aussieht:

def create 

    respond_to do |format| 

    @actions = [] 
    save_succeeded = true 
    params[:action].each do |action| 
     new_action = Action.new(type: action.type, time: action.time) 
     save_succeeded = false unless new_action.save 
     @actions << new_action 
    end 

    if save_succeeded 
     format.json { render json: @actions, status: :created } 
    else 
     format.json { render json: @actions.errors, status: 501 } 
    end 
    end 
end 

Wenn ich eine Post-Anforderung an den Controller (/actions.json) wie folgt an:

[{ "type": 0, "time": 1234567890 },{ "type": 0, "time": 1234567891 }] 

ich wieder eine leere bekommen Array [] und ein Statuscode 201 Created.

Das bedeutet, die save_succeeded Variable ist immer noch wahr, aber die Aktionen wurden nicht zum Array hinzugefügt. Außerdem sind die Aktionen nicht in meiner Datenbank.

Was mache ich falsch? Was übersehe ich?

Antwort

0

würde ich den Code ein wenig Refactoring:

def create 
    actions = params[:action].inject([]) do |memo, action| 
    memo << Action.create!(type: action[:type], time: action[:time]) 
    end 

    render json: @actions, status: :created 

    rescue ActiveRecord::RecordInvalid => e  
    render json: e.message, status: 501 
    end 
end 

Paar bemerkenswerte Veränderungen:

  • Verwendung create! und rescue ActiveRecord::RecordInvalid - create! eine ActiveRecord::RecordInvalid erhöhen wird, wenn der Speichervorgang fehlschlägt. Dann wird der Rettungsblock die Ausnahme retten und Sie können eine nette Fehlermeldung rendern.

  • können Sie nicht verwenden action.time, weil params ist ein Hash, kein Objekt.

  • Wenn Sie ein Array erstellen möchten, das später gerendert werden soll, können Sie inject verwenden.

  • Wenn Sie etwas Atomizität haben möchten (entweder ist alles erstellt oder nichts!), Können Sie das Ganze in einen Transaktionsblock wickeln.

Es ist erwähnenswert, dass ich nicht den Code oben getestet, aber es sollte Ihnen eine Richtung und (vielleicht) es wird ein Drop-in-Ersatz sein.

Hoffe, dass hilft!

+0

Vielen Dank für Ihre Antwort! Es hat mich in eine neue Richtung gelenkt, um es auszuprobieren (Parameter als Hash) und ich habe eine ähnliche Lösung implementiert. Ich habe jedoch immer noch ein fast ähnliches Problem wie zuvor: Ich bekomme keine Fehlermeldung, sondern einen Statuscode von 201 (Created) mit einem leeren Array und ohne hinzugefügte Aktionen. Da die Implementierung so schwierig ist, werde ich höchstwahrscheinlich mit einer Implementierung arbeiten, die nur einzelne Anforderungen akzeptiert und nur eine große Anzahl von Anfragen stellen muss. Vielen Dank für Ihre Hilfe! – NerdyTherapist