Hartl Ruby on Rails教程4 ch 10,用户编辑测试失败

时间:2016-09-22 19:51:18

标签: ruby-on-rails ruby ruby-on-rails-4 railstutorial.org ruby-on-rails-5

我正在练习Ruby on Rails,试图根据Hartl的教程创建一个自定义网站。到目前为止情况一直很顺利,但我在用户编辑测试中遇到错误“使用友好转发成功编辑”,其中用户在登录后没有重定向回编辑页面。这是我收到的错误消息:< / p>

FAIL["test_successful_edit_with_friendly_forwarding", UsersEditTest, 3.1409137547016144]
 test_successful_edit_with_friendly_forwarding#UsersEditTest (3.14s)
    Expected response to be a redirect to <http://www.example.com/users/787258272/edit> but was a redirect to <http://www.example.com/users/787258272>.
    Expected "http://www.example.com/users/787258272/edit" to be === "http://www.example.com/users/787258272".
    test/integration/users_edit_test.rb:23:in `block in <class:UsersEditTest>'

我觉得这个解决方案非常简单,我错过了,但我似乎无法弄清楚它是什么。

这是我的users_controller:

class UsersController < ApplicationController
  before_action :logged_in_user, only: [:edit, :update]
  before_action :correct_user,   only: [:edit, :update]

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

  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)
    if @user.save
      log_in @user
      flash[:success] = "Account created, welcome to Amplifire Energetics!"
      redirect_to @user
    else
      render 'new'
    end
  end

  def edit
  end

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

  private

    def user_params
      params.require(:user).permit(:name, :email, :password,
                                   :password_confirmation)
    end

    # Before filters

    # Confirms a logged-in user.
    def logged_in_user
      unless logged_in?
        flash[:danger] = "Please log in."
        redirect_to login_url
      end
    end

    # Confirms the correct user.
    def correct_user
      @user = User.find(params[:id])
      redirect_to(root_url) unless current_user?(@user)
    end
end

这是我的sessions_controller:

class SessionsController < ApplicationController
  def new
  end

  def create
    # Finds user in databse by email
    @user = User.find_by(email: params[:session][:email].downcase)
    # Authenticates user based on password
    if @user && @user.authenticate(params[:session][:password])
      log_in @user
      params[:session][:remember_me] == '1' ? remember(@user) :    forget(@user)
      redirect_back_or @user
    else
      flash.now[:danger] = "Invalid email/password combination"
      render 'new'
    end
  end

  def destroy
    log_out if logged_in?
    redirect_to root_url
  end
end

这是我的sessions_helper

module SessionsHelper

    # Logs in user 
    def log_in(user)
        session[:user_id] = user.id
    end

    # Remebers user in persistent session
    def remember(user)
        user.remember
        cookies.permanent.signed[:user_id] = user.id
        cookies.permanent[:remember_token] = user.remember_token
    end

    # Returns true if the given user is the current user.
    def current_user?(user)
        user == current_user
    end

    # Returns current logged in user
    def current_user
        if (user_id = session[:user_id])
            @current_user ||= User.find_by(id: session[:user_id])
        elsif (user_id = cookies.signed[:user_id])
            user = User.find_by(id: user_id)
            if user && user.authenticated?(cookies[:remember_token])
                log_in user
                @current_user = user
            end
        end
    end

    # Returns true if user logged in
    def logged_in?
        !current_user.nil?
    end

    # Logs out user
    def log_out
        session.delete(:user_id)
        @current_user = nil
    end

    # Forgets a persistent session
    def forget(user)
        user.forget
        cookies.delete(:user_id)
        cookies.delete(:remember_token)
    end

    # Logs out current user
    def log_out
        forget(current_user)
        session.delete(:user_id)
        @current_user = nil
    end

    # Redirects to stored location (or to the default).
    def redirect_back_or(default)
        redirect_to(session[:forwarding_url] || default)
        session.delete(:forwarding_url)
    end

    # Stores the URL trying to be accessed.
    def store_location
        session[:forwarding_url] = request.original_url if request.get?
    end

end

这是我的路线档案:

Rails.application.routes.draw do

  get 'sessions/new'

  get 'users/new'

  root 'static_pages#home'
  get '/help',            to: 'static_pages#help'
  get '/about',           to: 'static_pages#about'
  get '/contact',         to: 'static_pages#contact'
  get '/signup',          to: 'users#new'
  post '/signup',         to: 'users#create'
  get '/login',           to: 'sessions#new'
  post '/login',          to: 'sessions#create'
  delete '/logout',       to: 'sessions#destroy'
  resources :users
end

这是我的users.yml文件:

example: 
    name: Lil Wayne
    email: wheezy@youngmoney.com
    password_digest: <%= User.digest('password') %>
    admin: true

archer: 
    name: Sterling Archer
    email: dutchess@isis.gov
    password_digest: <%= User.digest('password') %>
    admin: false

这是我的用户模型文件:

class User < ApplicationRecord
    attr_accessor :remember_token
    before_save :downcase_email
    validates :name,  presence: true, length: { maximum: 50 }
    EMAIL_REGEX = /\A([\w+\-].?)+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i
    validates :email, presence: true, length: { maximum: 245 },
                      format: { with: EMAIL_REGEX },
                      uniqueness: { case_sensitive: false }
    has_secure_password 
    validates :password, presence: true, length: { minimum: 6 }, allow_nil: true

    class << self
        # Returns hash digest of given string
        def digest(s)
            cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
                                                        BCrypt::Engine.cost
            BCrypt::Password.create(s, cost: cost)
        end

        # Returns random token
        def new_token
            SecureRandom.urlsafe_base64
        end
    end

    # Remembers user in database for persistent sessions
    def remember
        self.remember_token = User.new_token
        update_attribute(:remember_digest, User.digest(remember_token))
    end

    def authenticated?(remember_token)
        return false if remember_digest.nil?
        BCrypt::Password.new(remember_digest).is_password?(remember_token)
    end

    # Forgets a user
    def forget
        update_attribute(:remember_digest, nil)
    end

    private 

        def downcase_email
            self.email = email.downcase
        end
end

这是我的users_edit_test:

require 'test_helper'

class UsersEditTest < ActionDispatch::IntegrationTest

  def setup
    @user = users(:example)
  end

  test "unsuccessful edit" do
    log_in_as(@user)
    get edit_user_path(@user)
    assert_template 'users/edit'
    patch user_path(@user), params: { user: { name:  "",
                                              email: "foo@invalid",
                                              password:              "foo",
                                              password_confirmation: "bar" } }
    assert_template 'users/edit'
  end

  test "successful edit with friendly forwarding" do
    get edit_user_path(@user)
    log_in_as(@user)
    assert_redirected_to edit_user_path(@user)
    name  = "Foo Bar"
    email = "foo@bar.com"
    patch user_path(@user), params: { user: { name:  name,
                                              email: email,
                                              password:              "",
                                              password_confirmation: "" } }
    assert_not flash.empty?
    assert_redirected_to @user
    @user.reload
    assert_equal name,  @user.name 
    assert_equal email, @user.email
  end

end

1 个答案:

答案 0 :(得分:2)

我发现了我的问题,我忘了将store_location方法添加到users_controller中的logged_in_user方法。