Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails exit controller after rendering

I have an action in my controller that I am having trouble with. This is my first rails app, so I'm not sure of the best practices surrounding rails.

I have a model called Group and a few actions that go in it's controller. I have written a test that should cause the controller to render an error in JSON because of an invalid Group ID. Instead of rendering and exiting, it looks like the controller is rendering and continuing to execute.

Test

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 action

# 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

In the controller, the first if statement executes: render :json => { :message => "group_id not found" } but @group.destroy is still being executed. This seems counter-intuitive to me, I would think that the render method should exit the controller.

Why is the controller not exiting after render is called?

The purpose of this block of code is to recover gracefully when no record can be found with the passed in ID. Is this the correct way of doing something like this?

like image 699
codysehl Avatar asked Nov 11 '12 16:11

codysehl


People also ask

Does Redirect_to return?

redirect_to is not return Keep in mind that redirect_to does not cause the action to stop executing. It is not like calling return in a Ruby method.

How can you tell Rails to render without a layout?

By default, if you use the :plain option, the text is rendered without using the current layout. If you want Rails to put the text into the current layout, you need to add the layout: true option and use the . text. erb extension for the layout file.

How do you render a partial?

Rendering a Partial View You can render the partial view in the parent view using the HTML helper methods: @html. Partial() , @html. RenderPartial() , and @html.

What does render do in Rails?

Rendering is the ultimate goal of your Ruby on Rails application. You render a view, usually . html. erb files, which contain a mix of HMTL & Ruby code.


2 Answers

Like @user1022209 said, you can add return to exit action:

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

About your code, I think i would write like this:

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
like image 181
Thanh Avatar answered Nov 17 '22 16:11

Thanh


Just simply add return; after render to exit the method body :)

I think render is just a method call, you call it, and the method will be placed on top of the stack which holds the sequence of execution of the method . After you finish render , you go back to the remove method and continue to execute the remaining. But you can avoid this problem by manually exit the remove method

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

like image 44
code4j Avatar answered Nov 17 '22 16:11

code4j