【发布时间】:2020-03-03 20:00:11
【问题描述】:
我正在尝试编写一个简单的 Rails API。在我的应用程序逻辑中,用户模型“has_many”预算和预算模型(自然)“belongs_to”用户。我正在尝试设置一个简单的身份验证系统以用于反应前端。在测试请求的过程中,我偶然发现了一些错误,这些错误似乎来自我的控制器。相关数据如下:
预算控制器
class Api::V1::BudgetsController < ApplicationController
def index
@budgets = Budget.all
render json: @budgets
end
def show
@budget = Budget.find(params[:id])
render json: @budget
end
def create
@budget = current_user.budgets.build(budget_params)
if @budget.save
render json: @budget, status: 201
else
render json: { errors: @budget.errors.full_messages }, status: 422
end
end
def destroy
@budget = Budget.find(params[:id])
@budget.destroy
end
private
def budget_params
params.require(:budget).permit(:start_date, :end_date, :income)
end
end
会话控制器
class Api::V1::SessionsController < ApplicationController
def create
user = User.find_by(email: session_params[:email])
if user
log_in user
render json: {
logged_in: true,
user
}
else
render json: {
status: 401,
error: 'Please try again'
}
end
end
def destroy
log_out if logged_in?
end
private
def session_params
params.require(:user).permit(:name, :email)
end
end
会话助手
module SessionsHelper
def log_in(user)
session[user_id] = user.id
end
def current_user
@current_user ||= User.find(session[:user_id]) if session[:user_id]
end
def logged_in?
!current_user.nil?
end
def log_out
session.clear
@current_user = nil
end
end
请求 RSpec 测试
require 'rails_helper'
RSpec.describe 'Budgets API', type: :request do
let!(:user) { create(:user) }
let!(:budgets) { create_list(:budget, 5, user_id: user.id) }
let(:budget_id) { budgets.first.id }
describe 'POST /api/v1/budgets' do
let(:valid_attributes) do
{
start_date: '2020-03-01',
end_date: '2020-03-31',
income: 7000
}
end
let(:invalid_attributes) do
{
start_date: '',
end_date: '',
income: ''
}
end
context 'when the request is valid' do
before(:each) { post '/api/v1/budgets', params: { budget: valid_attributes } }
it 'creates a budget' do
expect(json['start_date']).to eq('2020-03-01')
end
it 'returns status code 201' do
expect(response).to have_http_status(201)
end
end
context 'when the request is invalid' do
before(:each) { post '/api/v1/budgets', params: { budget: invalid_attributes } }
it 'returns status code 422' do
expect(response).to have_http_status(422)
end
end
end
end
我得到的错误如下:
Failures:
1) Budgets API POST /api/v1/budgets when the request is valid creates a budget
Failure/Error: @budget = current_user.budgets.build(budget_params)
NoMethodError:
undefined method `budgets' for nil:NilClass
# ./app/controllers/api/v1/budgets_controller.rb:14:in `create'
# ./spec/requests/budgets_spec.rb:62:in `block (4 levels) in <main>'
# ./spec/rails_helper.rb:73:in `block (3 levels) in <top (required)>'
# ./spec/rails_helper.rb:72:in `block (2 levels) in <top (required)>'
2) Budgets API POST /api/v1/budgets when the request is valid returns status code 201
Failure/Error: @budget = current_user.budgets.build(budget_params)
NoMethodError:
undefined method `budgets' for nil:NilClass
# ./app/controllers/api/v1/budgets_controller.rb:14:in `create'
# ./spec/requests/budgets_spec.rb:62:in `block (4 levels) in <main>'
# ./spec/rails_helper.rb:73:in `block (3 levels) in <top (required)>'
# ./spec/rails_helper.rb:72:in `block (2 levels) in <top (required)>'
3) Budgets API POST /api/v1/budgets when the request is invalid returns status code 422
Failure/Error: @budget = current_user.budgets.build(budget_params)
NoMethodError:
undefined method `budgets' for nil:NilClass
# ./app/controllers/api/v1/budgets_controller.rb:14:in `create'
# ./spec/requests/budgets_spec.rb:74:in `block (4 levels) in <main>'
# ./spec/rails_helper.rb:73:in `block (3 levels) in <top (required)>'
# ./spec/rails_helper.rb:72:in `block (2 levels) in <top (required)>'
任何帮助将不胜感激。
【问题讨论】:
-
SessionsController 和 SessionsHelper 似乎与 BudgetsController 没有关系。你也在用设计吗? ApplicationController 中是否还有更多代码?
-
SessionsHelper 模块包含在 ApplicationController 中
标签: ruby-on-rails ruby rspec