2012-11-11 12 views
7

Ho un'azione nel mio controller che ho problemi con. Questa è la mia prima app per rails, quindi non sono sicuro delle migliori pratiche che circondano le rotaie.Rails exit controller after rendering

Ho un modello chiamato Gruppo e alcune azioni che vanno nel suo controller. Ho scritto un test che dovrebbe causare al controller di visualizzare un errore in JSON a causa di un ID di gruppo non valido. Invece di eseguire il rendering e l'uscita, sembra che il controller stia eseguendo il rendering e continui a essere eseguito.

prova azione

test 'should not remove group because of invalid group id' do 
    post(:remove, {'group_id' => '3333'}) 
    response = JSON.parse(@response.body) 
    assert_response :success 
    assert_equal 'Success', response['message'] 
end 

controller

# Post remove 
# group_id 
def remove 
    if((@group = Group.find_by_id(params[:group_id])) == nil) 
     render :json => { :message => "group_id not found" } 
    end 

    @group.destroy 
    if(!Group.exists?(@group)) 
     render :json => { :message => "Success" } 
    else 
     render :json => { :errors => @group.errors.full_messages } 
    end 
end 

Nel controllore, la prima istruzione if esegue: render :json => { :message => "group_id not found" } ma @group.destroy è ancora in corso. Mi sembra controintuitivo, penserei che il metodo di rendering debba uscire dal controller.

Perché il controller non esce dopo il render viene chiamato?

Lo scopo di questo blocco di codice è recuperare con garbo quando non è possibile trovare record con l'ID passato. È questo il modo corretto di fare qualcosa del genere?

risposta

15

Come @ user1022209 Detto questo, è possibile aggiungere il ritorno per uscire azione:

render(:json => { :message => "group_id not found" }) and return 

proposito il codice, penso che vorrei scrivere così:

def remove 
    if(!Group.exists?(params[:group_id]) 
    render :json => { :message => "group_id not found" } 
    else 
    @group = Group.find(params[:group_id] 
    @group.destroy 
    if @group.destroyed? 
     render :json => { :message => "Success" } 
    else 
     render :json => { :errors => @group.errors.full_messages } 
    end 
    end 
end 
+0

Eccellente. L'aggiunta di un reso funzionava alla grande. – codysehl

7

Basta semplicemente aggiungere return; dopo render per uscire dal corpo del metodo :)

Credo render è solo una chiamata di metodo, si chiama, e il metodo sarà posto sulla parte superiore della pila che contiene la sequenza di esecuzione del metodo. Dopo aver completato render, si torna al metodo remove e si continua a eseguire il rimanente. Ma è possibile evitare questo problema manualmente uscire il metodo remove

It is my drawing to illustrate the concept described by the words above

Problemi correlati