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被调用后不退出?

此代码块的目的是在使用传入的 ID 找不到任何记录时优雅地恢复。这是做这样的事情的正确方法吗?

4

2 回答 2

17

就像@user1022209 所说,您可以添加返回退出操作:

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;之后添加:)render

我认为render只是一个方法调用,你调用它,该方法将被放置在堆栈的顶部,该堆栈保存了该方法的执行顺序。完成后render,您将返回该remove方法并继续执行其余部分。但是您可以通过手动退出该 remove方法来避免此问题

这是我的图来说明上面的话所描述的概念

于 2012-11-11T17:00:31.753 回答