SeekingTruth
SeekingTruth

Reputation: 1054

Why is it stating I am rendering or calling render twice?

I have written the following test which tries to update an already published post to saved. Meaning the user has published a post and now wants to mark it as saved. Which I do not allow.

it "should not update a post from published to saved" do
  @post = FactoryGirl.create(:post, blog_id: @blog.id, saved: false, published: true)
  put :update, :id => @post.id, post: {title: 'Sample Title', content: @post.content, saved: true}
  expect(response.status).to eql 422
end

This particular test states:

AbstractController::DoubleRenderError: Render and/or redirect were called multiple times in this action.

Which should not be the case because if we look at the method thats throwing it:

def post_controller_save(post, params)
  do_not_save_published_post(post, params)
  binding.pry
  publish_post(post, params)
  if post.save
    set_tags(post, params)
    set_categories(post, params)
    render json: post, status: 200
  else
    render json: {:errors => post.errors}, status: 422
  end
end

The first check we do is do_not_save_published_posts(post, params) (notice the binding.pry after it).

So if we follow this, we see the method in question (which is a private method):

def do_not_save_published_post(post, params)
  if (post.published && params[:post][:saved])
    binding.pry
    render json: {:errors => 'Cannot save a published post.'}, status: 422
    return
  end
end

This method checks if the post in question is published. and that the params for the post object contains a saved parameter. If both of these are true, we will render an error and return. The key here is to notice this binding.pry.

In the test, it reaches this break point and then typing exit causes the return to be skipped and the binding.pry out side this method to be caught.

This SHOULD NOT HAPPEN. It should render me json with a status of 422. Is the fact that this, do_not_save_published_post is a private method a contributing factor?

Upvotes: 0

Views: 125

Answers (1)

Mike Campbell
Mike Campbell

Reputation: 7978

Your call to do_not_save_published_post is just an ordinary method call, and returning from this method will behave like normal Ruby in that it will continue executing code after the method call.

You probably want to change your do_not_save_published_post to published_post?, move it to your model, have it return a boolean, and do your render logic in the controller.

Upvotes: 1

Related Questions