【问题标题】:NoMethodError: undefined method 'user' for nil:NilClassNoMethodError:nil 的未定义方法“用户”:NilClass
【发布时间】:2015-07-27 15:40:48
【问题描述】:

我正在阅读APIs on Rails 这本书,并且非常卡在第 5 章中,试图测试会话控制器。我收到以下错误,似乎无法追踪。有没有很好的方法来寻找这些类型的错误?我错过了什么?

 1) Api::V1::SessionsController POST #create when the credentials are correct returns the user record corresponding to the given credentials
 Failure/Error: post :create, { session: credentials }
 NoMethodError:
   undefined method `user' for nil:NilClass

应用在 Rails 4.0.2、Ruby 2.2.1 中

这是我的测试:

require 'spec_helper'

describe Api::V1::SessionsController do

  describe "POST #create" do

    before(:each) do
      @user = FactoryGirl.create :user
    end

    context "when the credentials are correct" do
      puts @user

      before(:each) do
        credentials = { email: @user.email, password: "12345678" }
        post :create, { session: credentials }
      end

      it "returns the user record corresponding to the given credentials" do
        @user.reload
        expect(json_response[:auth_token]).to eql @user.auth_token
      end

      it { should respond_with 200 }
    end


  end


end

这里是会话控制器:

class Api::V1::SessionsController < ApplicationController
  respond_to :json

  def create
    user_password = params[:session][:password]
    user_email = params[:session][:email]
    user = user_email.present? && User.find_by(email: user_email)

    if user.valid_password? user_password
      sign_in user, store: false
      user.generate_authentication_token!
      user.save
      render json: user, status: 200, location: [:api, user]
    else
      render json: { errors: "Invalid email or password" }, status: 422
    end
  end

end

用户控制器:

class Api::V1::UsersController < ApplicationController
  respond_to :json

  def show
    respond_with User.find(params[:id])
  end

  def create
    user = User.new(user_params)
    if user.save
      render json: user, status: 201, location: [:api, user]
    else
      render json: { errors: user.errors }, status: 422
    end
  end

  def update
    user = User.find(params[:id])

    if user.update(user_params)
      render json: user, status: 200, location: [:api, user]
    else
      render json: { errors: user.errors }, status: 422
    end
  end

  def destroy
    user = User.find(params[:id])
    user.destroy
    head 204
  end

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


end

routes.rb:

require 'api_constraints'

MarketPlaceApi::Application.routes.draw do
  mount SabisuRails::Engine => "/sabisu_rails"
  devise_for :users
  # Api definition
  namespace :api, defaults: { format: :json }, constraints: { subdomain: 'api' }, path: '/'  do
    scope module: :v1, constraints: ApiConstraints.new(version: 1, default: true) do
      resources :users, :only => [:show, :create, :update, :destroy]
      resources :sessions, :only => [:create, :destroy]
    end
  end
end

以及用户模型:

class User < ActiveRecord::Base
  validates :auth_token, uniqueness: true


  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  before_create :generate_authentication_token!

  def generate_authentication_token!
    begin
      self.auth_token = Devise.friendly_token
    end while self.class.exists?(auth_token: auth_token)
  end
end

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4 devise


    【解决方案1】:

    您是否已将 devise_helper 添加到 spec/rails_helper.rb 中?

    RSpec.configure do |config|
      ...
      config.include Devise::TestHelpers, type: :controller
      ...
    end
    

    【讨论】:

    • 这正是问题所在。非常感谢!
    【解决方案2】:

    改变

    if user.valid_password? user_password
    

    到:

    if user and valid_password? user_password
    

    或:

    if user && valid_password?(user_password)
    

    在您的 session_controller.rb 文件中。

    【讨论】:

      【解决方案3】:

      你有用户工厂吗?

      FactoryGirl.define do
        factory :user do
          username user
          email user@user.com
          password '12345678'
          password_confirmation { '12345678' }
        end
      end
      

      您需要定义它以便 FactoryGirl 可以创建用户

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-02
        • 1970-01-01
        • 2021-10-25
        • 2014-06-01
        • 1970-01-01
        相关资源
        最近更新 更多