Синатра неопределенный метод `user_id 'для nil: NilClass - PullRequest
0 голосов
/ 10 февраля 2020

Я продолжаю сталкиваться с этой ошибкой в ​​моем 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

Helpers.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>'

1 Ответ

0 голосов
/ 11 февраля 2020

Согласно запросу

SELECT  "gigs".* FROM "gigs" WHERE "gigs"."id" = ? LIMIT 1  [["id", 0]]

Идентификатор, который вы пытаетесь найти, равен нулю, поэтому @gig равен нулю (если у вас действительно нет записи с идентификатором 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
...