修复 Rails 控制器
Fixing Rails Controller
我正在尝试编写一个简单的 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)>'
如有任何帮助,我们将不胜感激。
current_user
是 nil
因为测试从未登录用户。仅仅创建用户是不够的,他们必须登录。
通常您会在 before
挂钩中执行此操作。
RSpec.describe 'Budgets API', type: :request do
let!(:user) { create(:user) }
before {
post("/api/v1/sessions",
params: {
user: { email: user.email }
}
)
}
任何知道用户电子邮件地址的人都可以访问您的API。我建议使用预先存在的 gem,例如 Devise.
,而不是滚动您自己的身份验证
我正在尝试编写一个简单的 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)>'
如有任何帮助,我们将不胜感激。
current_user
是 nil
因为测试从未登录用户。仅仅创建用户是不够的,他们必须登录。
通常您会在 before
挂钩中执行此操作。
RSpec.describe 'Budgets API', type: :request do
let!(:user) { create(:user) }
before {
post("/api/v1/sessions",
params: {
user: { email: user.email }
}
)
}
任何知道用户电子邮件地址的人都可以访问您的API。我建议使用预先存在的 gem,例如 Devise.
,而不是滚动您自己的身份验证