ruby - 用于 nil:NilClass 的 Sinatra 未定义方法“user_id”
问题描述
我一直在我的 application_controller 中遇到这个错误,我似乎无法找出问题所在。
在我不得不编辑演出之前,一切似乎都很好。我知道我需要重构我的代码,否则我会再次遇到这个问题。
任何帮助表示赞赏!
错误-
NoMethodError at /gigs/:id/edit
undefined method `user_id' for nil:NilClass
应用控制器
require './config/environment'
class ApplicationController < Sinatra::Base
configure do
set :public_folder, 'public'
set :views, 'app/views'
enable :sessions
set :session_secret, "secret"
end
get "/" do
erb :welcome
end
get "/signup" do
erb :'/users/signup'
end
post "/signup" do
if User.find_by(:email => params["email"])
puts "Sorry, there is already an account using this email address"
redirect "/login"
else
user = User.create(params)
if user.save
session[:user_id] = user.id
redirect "/"
else
puts "Sorry. All fields must be filled out."
redirect "/signup"
end
end
# @user = User.new(name: params["name"], email: params["email"], password: params["password"])
# @user.save
#@user = User.new(params)
# @user.save
#session[:user_id] = @user.id
#puts params
#redirect '/users/home'
#session[:name] = params[:name]
end
get "/login" do
erb :'users/login'
end
post '/login' do
@user = User.find_by(:email => params["email"])
if @user && @user.authenticate(params["password"])
session[:user_id] = @user.id
redirect "/home"
end
redirect "/login"
end
get '/home' do
@user = User.find(session[:user_id])
erb :'users/home'
end
get '/gigs' do
if Helpers.is_logged_in?(session)
@user = Helpers.current_user(session)
@gigs = Gig.all
#if @user != nil
# @gigs = Gig.where(:user_id => @user.id)
erb :'gigs/index'
else
redirect "/login"
end
end
post '/gigs' do
@user = Helpers.current_user(session)
@gig = @user.gigs.create(params)
if @gig.save
puts "Gig has been saved."
else
puts "Please try again."
end
redirect "/gigs"
end
get '/gigs/new' do
if Helpers.is_logged_in?(session)
erb :'gigs/new'
else
redirect "/login"
end
end
get '/gigs/:id' do
if Helpers.is_logged_in?(session)
@user = Helpers.current_user(session)
@gig = Gig.find_by_id(params["id"])
if @gig.id == @gig.user_id
erb :'gigs/show'
else
redirect "/login"
end
else
redirect "/login"
end
end
get '/gigs/:id/edit' do
if Helpers.is_logged_in?(session)
@user = Helpers.current_user(session)
@gig = Gig.find_by_id(params[:id]) #["id"]
if @user.id == @gig.user_id
erb :'gigs/edit'
else
redirect "/login"
end
else
redirect "/login"
end
end
patch '/gigs/:id' do
@user = Helpers.current_user(session)
@gig = Gig.find_by_id(params["id"])
if @user.id == @gig.user_id
@gig.update(params["gig"])
redirect "/gigs/#{@gig.id}"
else
redirect "/login"
end
end
delete '/gigs/:id' do
@user = Helpers.current_user(session)
@gig = Gig.find_by_id(params["id"])
if @user.id == @gig.user_id
@gig.destroy
redirect "/gigs"
else
redirect "/login"
end
end
get '/logout' do
session.clear
redirect "/"
end
end
助手.rb
class Helpers
def self.is_logged_in?(session)
if session[:user_id] != nil
true
else
false
end
end
def self.current_user(session)
if self.is_logged_in?(session)
@user = User.find_by_id(session[:user_id])
end
end
end
架构
ActiveRecord::Schema.define(version: 20200209173236) do
create_table "genres", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "gigs", force: :cascade do |t|
t.string "bands"
t.string "location"
t.date "date"
t.string "time"
t.integer "user_id"
end
create_table "users", force: :cascade do |t|
t.string "name"
t.string "email"
t.string "password_digest"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
错误日志-
D, [2020-02-10T08:58:54.511675 #10068] DEBUG -- : ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
D, [2020-02-10T08:58:54.536858 #10068] DEBUG -- : User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 3]]
D, [2020-02-10T08:58:54.550769 #10068] DEBUG -- : Gig Load (0.1ms) SELECT "gigs".* FROM "gigs" WHERE "gigs"."id" = ? LIMIT 1 [["id", 0]]
2020-02-10 08:58:54 - NoMethodError - undefined method `user_id' for nil:NilClass:
/Users/melc/nyc-shows/app/controllers/application_controller.rb:115:in `block in <class:ApplicationController>'
解决方案
根据查询
SELECT "gigs".* FROM "gigs" WHERE "gigs"."id" = ? LIMIT 1 [["id", 0]]
您要查找的 ID 为零,因此@gig
为空(除非您确实有 id 为 0 的记录)
@gig = Gig.find_by_id(params["id"])
if @user.id == @gig.user_id
你可以像这样防止这种情况
if @gig.nil? || @user.id == @gig.user_id
但我猜问题在于 url 的生成而不是这种方法。
你也可以像这样重构函数
get '/gigs/:id/edit' do
@user = Helpers.current_user(session)
@gig = Gig.find_by_id(params[:id])
redirect "/login" if @user.nil?
redirect "/invalid_gig_page" if @gig.nil? || @user.id != @gig.user_id
erb :'gigs/edit'
end
推荐阅读
- java - 比较Java中两个对象的内容
- git - Visual Studio Code 不显示本地分支
- python-3.x - Python Dask 模块错误.. AttributeError: '_io.TextIOWrapper' 对象没有属性 'startswith'
- debugging - 使用 OpenOCD 调试 STM32,用于 VSCODE 的 STM32 将无法工作或闪烁,可能是配置问题?
- c# - Mac 上的 VS 代码....“程序 'xxxxxxxxx' 已退出,代码为 0 (0x0)”... 期待跨步工作,但单击时调试退出
- .net-core - 我是否需要最新的 .NET Core 补丁才能运行新代码?
- visual-c++ - 我可以通过 NULL 调制解调器电缆通过一个(USB 到 SerialPort 转换器)读取和写入到同一台计算机上的另一个(SerialPort 到 USB)吗?
- reactjs - 如何将道具传递给我们还不知道所需类型的 React 子组件
- c++ - 我得到变量 a 的垃圾值。我必须输入 2 个值并使用 2 个类 - 基类和派生类打印它们的总和
- php - Laravel 集合:使用两个 cloumns 过滤