2017-02-03 2 views
1

Ich mache eine Rails JSON API, die Service-Objekte in Controller-Aktionen verwendet und basierend auf dem, was im Service passiert, muss ich richtig json rendern. Das Beispiel sieht so aus.Service-Objekt-Status

star_service.rb

class Place::StarService 
    def initialize(params, user) 
    @place_id = params[:place_id] 
    @user = user 
    end 

    def call 
    if UserStaredPlace.find_by(user: user, place_id: place_id) 
     return #star was already given 
    end 

    begin 
     ActiveRecord::Base.transaction do 
     Place.increment_counter(:stars, place_id) 
     UserStaredPlace.create(user: user, place_id: place_id) 
     end 
    rescue 
     return #didn't work 
    end 

    return #gave a star 
    end 

    private 

    attr_reader :place_id, :user 
end 

places_controller.rb

def star 
    foo_bar = Place::Star.new(params, current_user).call 

    if foo_bar == #sth 
    render json: {status: 200, message: "sth"} 
    elsif foo_bar == #sth 
    render json: {status: 200, message: "sth"} 
    else 
    render json: {status: 400, message: "sth"} 
end 

Und meine Frage ist, wenn ich Klartext von Service-Objekt zurückgeben sollte oder es liegt ein besserer Ansatz?

Rendering Ansichten mit Daten

Antwort

1

Es wird ... aber immer noch natürlich opinionated werden, Daten zurückgegeben, Umleitung usw. die Verantwortlichkeiten der Controller werden. Also alle Daten, Klartext und andere Dinge, die Sie in Ihrem Controller behandeln müssen.

Dienstobjekt müssen eine einzige öffentliche Methode für die Durchführung einer großen komplexen Operation bereitstellen. Und offensichtlich muss diese Methode einen einfachen Wert zurückgeben, der dem Controller mitteilt, ob der Vorgang erfolgreich abgeschlossen wurde oder nicht. So muss es true oder false sein. Vielleicht ein erkennbares Ergebnis (Objekt, einfacher Wert) oder errors Hash. Es ist natürlich der ideale Anwendungsfall, aber es ist der Punkt.

Für Ihren Anwendungsfall kann Ihr Dienst die Nachricht zurückgeben oder false. Und dann rendern Controller diese Nachricht als json.

Und Ihre star Methode in Ihrem Controller leben müssen, privat wohl und sieht wie folgt aus:

def star 
    foo_bar = Place::Star.new(params, current_user).call 

    if foo_bar 
    render json: {status: 200, message: foobar} 
    else 
    render json: {status: 400, message: "Failed"} 
    end 
end 

Ihr Service:

class Place::StarService 
    def initialize(params, user) 
    @place_id = params[:place_id] 
    @user = user 
    end 

    def call 
    if UserStaredPlace.find_by(user: user, place_id: place_id) 
     return "Message when star is already given" 
    end 

    begin 
     ActiveRecord::Base.transaction do 
     Place.increment_counter(:stars, place_id) 
     UserStaredPlace.create(user: user, place_id: place_id) 
     end 
    rescue 
     return false 
    end 

    return "Message if gave a star" 
    end 

    private 

    attr_reader :place_id, :user 
end 
+0

Sie sagen also, dass ich Dienst löschen sollte und Logik bewegen zum Prüfer? –

+0

Entschuldigung, ich überdenken die Antwort ein wenig und aktualisiert es. Nein, Sie müssen den Dienst nicht löschen. Services ist Leben! :) Service liefert Ergebnis oder falsch. Die Aktion des Controllers (möglicherweise unter Verwendung einer privaten Methode) rendert das Ergebnis, wenn es nicht "falsch" ist – VAD