1

Michael Hartl のRuby on Rails Tutorial, 2nd Ed、第 9 章の演習 6 では、次のように述べています。

サインインしたユーザーは、Users コントローラーの new および create アクションにアクセスする必要はありません。そのようなユーザーがこれらのページにアクセスしようとすると、ルート URL にリダイレクトされるように手配します。

このための rspec テストをどのように書くのでしょうか? 私はこれを試しました

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

do/end ブロックの使用、ユーザー属性のハッシュの追加などを試しました。上記のスニペットは、公式サンプル コードの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

Users コントローラーの new および create アクションへのアクセスを制限するという実際の目的については、次の行を追加して解決しました。

admin_user if signed_in?

手でテストしたので、これが機能することを知っています。唯一の問題は、rspec テストを作成できないことです。このチュートリアルに従って作成したコードは、github で入手できます。

このエラーが発生するのはなぜですか? 私は何を間違っていますか?解決策は何ですか?ありがとうございました。

4

2 に答える 2

2

私は自分でチュートリアルを実行しているだけで、まさにこの演習を行っているので、私は確かに専門家ではありません. しかし、私はあなたとは違った解釈をしています。私が理解しているように、管理者以外のユーザーだけでなく、サインインしているユーザーがユーザーの新規または作成操作を試行した場合、要求はルート ページにリダイレクトすることです。

いずれにせよ、私が見た中で最もエレガントな解決策は、https: //stackoverflow.com/a/11287798/1008891 で説明されているように before_filter を使用することです

于 2013-02-02T03:03:11.750 に答える
1

ポール、手がかりをありがとう。問題を解決しました。

追加して目的を解決しようとしました

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 ブロックで囲むことです。そうしないと、作成アクションによって証明されるように、コードが継続しているように見えます。これは新しいアクションではそれほど問題ではありませんでした。単純な 3 項式の後、インスタンス変数のみが割り当てられたからです。

結論として、私はポールからの非常に良い手がかりと、良い夜の睡眠が必要です. ありがとうございました。

于 2013-01-14T17:19:28.293 に答える