【问题标题】:Chapter 9, Exercise 6, Michael Hartl's Ruby on Rails Tutorial: What is the solution?第 9 章,练习 6,Michael Hartl 的 Ruby on Rails 教程:解决方案是什么?
【发布时间】:2013-01-14 06:21:15
【问题描述】:

在 Michael Hartl 的 Ruby on Rails 教程,第二版,第 9 章的练习 6 中说:

已登录的用户没有理由访问新的和创建的操作 用户控制器。安排将此类用户重定向到 如果他们确实尝试访问这些页面,则为根 URL。

如何为此编写 rspec 测试?我试过这个

  describe "POST on Users#create" do
    before { post users_path }
    specify { response.should redirect_to(root_path) }
  end

我尝试过使用 do/end 块、添加用户属性的哈希等。上面的 sn-p 已添加到 the official sample code 中的 #162 行。他们都给我这个错误:

Failures:

  1) Authentication authorization as non-admin user POST on Users#create 
     Failure/Error: before { post users_path }
     AbstractController::DoubleRenderError:
       Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like "redirect_to(...) and return".
     # ./app/controllers/users_controller.rb:27:in `create'
     # ./spec/requests/authentication_pages_spec.rb:72:in `block (5 levels) in <top (required)>'

Finished in 2.72 seconds
88 examples, 1 failure

至于在用户控制器中限制对新操作和创建操作的访问的实际目标,我通过添加以下行来解决它们:

admin_user if signed_in?

我知道这是可行的,因为我手动测试了它。唯一的问题是我无法为其编写 rspec 测试。 The code I have created as I follow this tutorial is available at github.

为什么会出现此错误?我究竟做错了什么?解决办法是什么?谢谢。

【问题讨论】:

  • 你的错误是Render and/or redirect were called multiple times in this action。您能否编辑您的问题以在您的UsersController 中添加create 方法的内容。
  • 您好 Paul,感谢您的回复。我已按要求编辑了我的帖子。但为了方便您,我的代码是in this link。其中,您应该能够看到我的用户控制器的全部荣耀。再次感谢您的帮助。

标签: ruby-on-rails-3.2 railstutorial.org ruby-1.9.3


【解决方案1】:

我自己只是在学习本教程,并且正在进行这个练习,所以我当然不是专家。但是,我对请求的解释与您不同。据我了解,如果 any 登录用户尝试用户新建或创建操作,而不仅仅是非管理员,请求将重定向到根页面。

无论如何,我见过的最优雅的解决方案是使用 https://stackoverflow.com/a/11287798/1008891 中描述的 before_filter

【讨论】:

    【解决方案2】:

    保罗,谢谢你的线索。我解决了这个问题。

    我试图通过添加来解决目标

    admin_user if signed_in?
    

    虽然这似乎在浏览器中工作,但在后台还有其他事情发生。在仔细研究了我的创建操作后,这是我所做的更改,并且 rspec 测试开始起作用:

        diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
    index 6e0fec8..53f8325 100644
    --- a/app/controllers/users_controller.rb
    +++ b/app/controllers/users_controller.rb
    @@ -8,8 +8,8 @@ class UsersController < ApplicationController
       end
    
       def new
    -    admin_user if signed_in?
    -    @user = User.new
    +    signed_in? ? admin_user : @user = User.new
    +    #@user = User.new
       end
    
       def show
    @@ -17,14 +17,17 @@ class UsersController < ApplicationController
       end
    
       def create
    -    admin_user if signed_in?
    -    @user = User.create(params[:user])
    -    if @user.save
    -      sign_in @user
    -      flash[:success] = "Welcome to the Sample App!"
    -      redirect_to @user
    -    else
    -      render 'new'
    +    if signed_in?
    +        admin_user
    +      else
    +      @user = User.create(params[:user])
    +      if @user.save
    +        sign_in @user
    +        flash[:success] = "Welcome to the Sample App!"
    +        redirect_to @user
    +      else
    +        render 'new'
    +      end
         end
       end
    

    解决方案是将代码包含在完整的 if/else 块中。如果我不这样做,则代码似乎会继续执行,正如创建操作所证明的那样。这对于新操作来说不是问题,因为在简单的三元之后,它只分配了一个实例变量。

    总之,我只需要保罗提供一个很好的线索,然后睡个好觉。谢谢。

    【讨论】:

    • 您能够解决自己的问题真是太好了!请将此标记为已接受的答案以供其他人参考:-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多