Rails by Example(由Michael Hartl撰写),第9.23课重定向将不起作用

时间:2013-04-18 23:27:48

标签: ruby-on-rails ruby authentication login railstutorial.org

我正在关注重定向的第9课,但重定向只是不起作用!我按照代码来写信无济于事。

This is my location in the online tutorial

Here is the current Github of the app

这个想法是 - 如果用户退出并点击受保护的页面(例如用户编辑页面),他将被发送到登录页面。(因为当您注销时不应该允许您编辑任何内容。)登录后,他返回到他之前点击的受保护页面(反对进入个人资料页面。)

这应该适用于本教程的当前部分,但事实并非如此。我已经包含了rspec和失败以防万一。

失败:

1) Authentication authorization for non-signed-in users when attempting to visit a protected page after signing in should render the desired protected page

 Failure/Error: page.should have_selector('title', text: 'Edit user')
   expected css "title" with text "Edit user" to return something

 # ./spec/requests/authentication_pages_spec.rb:65:in `block (6 levels) in <top (required)>'

authentication_pages_spec.rb

require 'spec_helper'

describe "Authentication" do
  subject { page }

  describe "signin page" do
    before { visit signin_path }

    it { should have_selector('h1',    text: 'Sign in') }
    it { should have_selector('title', text: 'Sign in') }
  end

  describe "signin" do
    before { visit signin_path }

    describe "with invalid information" do
      before { click_button "Sign in" }

      it { should have_selector('title', text: 'Sign in') }
      it { should have_selector('div.alert.alert-error', text: 'Invalid') }

        describe "after visiting another page" do
        before { click_link "Home" }
        it { should_not have_selector('div.alert.alert-error') }
        end  
    end

    describe "with valid information" do
      let(:user) { FactoryGirl.create(:user) }
      before do
        fill_in "Email",    with: user.email.upcase
        fill_in "Password", with: user.password
        click_button "Sign in"
    end

      it { should have_selector('title', text: user.name) }
      it { should have_link('Profile', href: user_path(user)) }
      it { should have_link('Settings', href: edit_user_path(user)) }
      it { should have_link('Sign out', href: signout_path) }
      it { should_not have_link('Sign in', href: signin_path) }

      describe "followed by signout" do
        before { click_link "Sign out" }
        it { should have_link('Sign in') }
      end
  end
end

  describe "authorization" do

    describe "for non-signed-in users" do
      let(:user) { FactoryGirl.create(:user) }

      describe "when attempting to visit a protected page" do
        before do
          visit edit_user_path(user)
          fill_in "Email",    with: user.email
          fill_in "Password", with: user.password
          click_button "Sign in"
        end

        describe "after signing in" do

          it "should render the desired protected page" do
            page.should have_selector('title', text: 'Edit user')
          end

          describe "when signing in again" do
            before do
              delete signout_path
              visit signin_path
              fill_in "Email",    with: user.email
              fill_in "Password", with: user.password
              click_button "Sign in"
            end

            it "should render the default (profile) page" do
              page.should have_selector('title', text: user.name) 
            end
          end
        end
      end
      describe "in the Users controller" do

        describe "visiting the edit page" do
          before { visit edit_user_path(user) }
          it { should have_selector('title', text: 'Sign in') }
        end

        describe "submitting to the update action" do
          before { put user_path(user) }
          specify { response.should redirect_to(signin_path) }
        end
      end
    end

    describe "as wrong user" do
      let(:user) { FactoryGirl.create(:user) }
      let(:wrong_user) { FactoryGirl.create(:user, email: "wrong@example.com") }
      before { sign_in user }

      describe "visiting Users#edit page" do
        before { visit edit_user_path(wrong_user) }
        it { should_not have_selector('title', text: full_title('Edit user')) }
      end

      describe "submitting a PUT request to the Users#update action" do
        before { put user_path(wrong_user) }
        specify { response.should redirect_to(root_path) }
      end
    end

  end
end

sessions_Controller.rb

class SessionsController < ApplicationController

  def new
  end

  def create
    user = User.find_by_email(params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      sign_in user
      redirect_to user
    else
      flash.now[:error] = 'Invalid email/password combination'
      render 'new'
    end
  end

  def destroy
    sign_out
    redirect_to root_url
  end
end

user_controllers.rb

class UsersController < ApplicationController
  before_filter :signed_in_user, only: [:edit, :update]
  before_filter :correct_user,   only: [:edit, :update]


  def show
    @user = User.find(params[:id])
  end

  def new
    @user = User.new
  end

  def edit
    # @user = User.find(params[:id])
  end

  def update
      if @user.update_attributes(params[:user])
      flash[:success] = "Profile updated"
      sign_in @user
      redirect_to @user
    else
      render 'edit'
    end
  end


  def create
    @user = User.new(params[:user])
    if @user.save
      sign_in @user
      flash[:success] = "Welcome to the Sample App!"
      redirect_to @user
    else
      render 'new'
    end
  end

  private

    def signed_in_user
      unless signed_in?
        store_location
        redirect_to signin_url, notice: "Please sign in."
      end
    end

    def correct_user
      @user = User.find(params[:id])
      redirect_to(root_path) unless current_user?(@user)
    end
end

session_helper.rb

module SessionsHelper

  def sign_in(user)
    cookies.permanent[:remember_token] = user.remember_token
    self.current_user = user
  end

  def signed_in?
    !current_user.nil?
  end

  def current_user=(user)
    @current_user = user
  end

  def current_user
    @current_user ||= User.find_by_remember_token(cookies[:remember_token])
  end

  def current_user?(user)
    user == current_user
  end

  def sign_out
    self.current_user = nil
    cookies.delete(:remember_token)
  end

  def redirect_back_or(default)
    redirect_to(session[:return_to] || default)
    session.delete(:return_to)
  end

  def store_location
    session[:return_to] = request.url
  end
end

edit.htmnl.erb

<% provide(:title, "Edit user") %> 
<h1>Update your profile</h1>

<div class="row">
  <div class="span6 offset3">
    <%= form_for(@user) do |f| %>
      <%= render 'shared/error_messages' %>

      <%= f.label :name %>
      <%= f.text_field :name %>

      <%= f.label :email %>
      <%= f.text_field :email %>

      <%= f.label :password %>
      <%= f.password_field :password %>

      <%= f.label :password_confirmation, "Confirm Password" %>
      <%= f.password_field :password_confirmation %>

      <%= f.submit "Save changes", class: "btn btn-large btn-primary" %>
    <% end %>

    <%= gravatar_for @user %>
    <a href="http://gravatar.com/emails">change</a>
  </div>
</div>

修改 * 开发日志 *

    Started POST "/sessions" for 127.0.0.1 at 2013-    04-17 22:20:22 -0400    
Processing by SessionsController#create as HTML    
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"aEDz4BcEpiAI+CQXcb6Fz8SHTP30NSqHZlzn4w1GvuQ=", "session"=>{"email"=>"alain.goldman@gmail.com", "password"=>    "[FILTERED]"}, "commit"=>"Sign in"}
  User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."email" = 'alain.goldman@gmail.com' LIMIT 1
Redirected to http://localhost:3000/users/1
Completed 302 Found in 451ms (ActiveRecord: 0.2ms)


Started GET "/users/1" for 127.0.0.1 at 2013-04-17 22:20:22 -0400
Processing by UsersController#show as HTML
  Parameters: {"id"=>"1"}
  User Load (0.3ms)  SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", "1"]]
  Rendered users/show.html.erb within layouts/application (1.1ms)
  Rendered layouts/_shim.html.erb (0.1ms)
  User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = 'sIGAbFoWQKYG0cjXhK5nWg' LIMIT 1
  Rendered layouts/_header.html.erb (3.9ms)
  Rendered layouts/_footer.html.erb (0.6ms)
Completed 200 OK in 195ms (Views: 192.9ms | ActiveRecord: 0.5ms)

1 个答案:

答案 0 :(得分:3)

哦,我看到的明显的事情是你的会话控制器(在create方法中),需要更改为使用redirect_back_or。这可能会解决它。