7

コントローラーに問題のあるアクションがあります。これは私の最初のRailsアプリなので、Railsを取り巻くベストプラクティスがわかりません。

Groupというモデルと、そのコントローラーで実行されるいくつかのアクションがあります。グループIDが無効なためにコントローラーがJSONでエラーをレンダリングするテストを作成しました。レンダリングして終了する代わりに、コントローラーがレンダリングして実行を継続しているように見えます。

テスト

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

コントローラのアクション

# 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

コントローラでは、最初のifステートメントが実行されます:render :json => { :message => "group_id not found" } しかし@group.destroy、まだ実行中です。これは私には直感に反しているように思えます。renderメソッドはコントローラーを終了する必要があると思います。

render呼び出された後にコントローラーが終了しないのはなぜですか?

このコードブロックの目的は、渡されたIDを持つレコードが見つからない場合に正常に回復することです。これはこのようなことをする正しい方法ですか?

4

2 に答える 2

17

@ user1022209 が言ったように、return を exit アクションに追加できます。

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

あなたのコードについて、私は次のように書くと思います:

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
于 2012-11-11T19:09:35.783 に答える
9

return;afterを追加してメソッド本体を終了するだけですrender:)

renderはただのメソッド呼び出しだと思います、あなたはそれを呼び出します、そしてメソッドはメソッドの実行シーケンスを保持するスタックの一番上に置かれます. が終了renderしたら、メソッドに戻りremove、残りのメソッドを引き続き実行します。ただし、 removeメソッドを手動で終了することで、この問題を回避できます

上記の言葉で説明されている概念を説明するための私の絵です

于 2012-11-11T17:00:31.753 に答える