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?
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.
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.
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.
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.
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With