为什么它说我渲染或调用渲染两次?

时间:2014-09-26 20:31:05

标签: render ruby-on-rails-4.1

我编写了以下测试,试图将已发布的帖子更新为已保存。意味着用户已发布帖子,现在想要将其标记为已保存。我不允许这样做。

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

此特定测试表明:

  

一个AbstractController :: DoubleRenderError:    在此操作中多次调用渲染和/或重定向。

不应该是这种情况,因为如果我们看一下投掷它的方法:

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

我们做的第一次检查是do_not_save_published_posts(post, params)(注意后面的binding.pry

因此,如果我们遵循这一点,我们会看到有问题的方法(这是一种私有方法):

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

此方法检查相关帖子是否已发布。并且post对象的params包含一个保存的参数。如果这两个都是真的,我们将呈现错误并返回。这里的关键是要注意这个binding.pry

在测试中,它到达此断点,然后键入exit会导致跳过返回,并且binding.pry将此方法捕获。{/ p>

这不应该发生。它应该让我json的状态为422.事实上,do_not_save_published_post是私有方法的一个促成因素吗?

1 个答案:

答案 0 :(得分:1)

你对do_not_save_published_post的调用只是一个普通的方法调用,从这个方法返回的行为与普通的Ruby一样,因为它会在方法调用后继续执行代码。

您可能希望将do_not_save_published_post更改为published_post?,将其移至模型,返回布尔值,并在控制器中执行渲染逻辑。