1

我正在練習Ruby on Rails,試圖根據Hartl的教程創建一個自定義網站。事情一直進展良好,但我在用戶編輯測試「友好轉發成功編輯」中出現錯誤,其中用戶在登錄後沒有重定向回編輯頁面。這是我得到的錯誤消息:Hartl Ruby on Rails教程4 ch 10,用戶編輯測試失敗

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: [email protected] 
    password_digest: <%= User.digest('password') %> 
    admin: true 

archer: 
    name: Sterling Archer 
    email: [email protected] 
    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+\-].?)[email protected][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: "[email protected]", 
               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 = "[email protected]" 
    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 

回答

2

我發現了什麼我的問題是,我忘了將store_location方法添加到users_controller中的logged_in_user方法。

相關問題