Reputation: 13
I'm following along with One Month Rails and I got stuck at the Pins Users and Associations video. I just can't figure out what's wrong with my code, any help would be appreciated.
When I try to access a pin that I'm not the user of, instead of an alert and redirect coming up I get:
NoMethodError in PinsController#edit
undefined method `pins' for nil:NilClass
Error message says something is wrong in this line:
def correct_user
@pin = current_user.pins.find_by(id: params[:id])
redirect_to pins_path, notice: "Not authorized to edit this pin" if @pin.nil?
end
I tried restarting the whole thing but I hit the same error.
Here is my pins_controller code:
class PinsController < ApplicationController
before_action :set_pin, only: [:show, :edit, :update, :destroy]
before_action :correct_user, only: [:edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
def index
@pins = Pin.all
end
def show
end
def new
@pin = current_user.pins.build
end
def edit
end
def create
@pin = current_user.pins.build(pin_params)
if @pin.save
redirect_to @pin, notice: 'Pin was successfully created.'
else
render action: 'new'
end
end
def update
if @pin.update(pin_params)
redirect_to @pin, notice: 'Pin was successfully updated.'
else
render action: 'edit'
end
end
def destroy
@pin.destroy
redirect_to pins_url
end
private
# Use callbacks to share common setup or constraints between actions.
def set_pin
@pin = Pin.find(params[:id])
end
def correct_user
@pin = current_user.pins.find_by(id: params[:id])
redirect_to pins_path, notice: "Not authorized to edit this pin" if @pin.nil?
end
# Never trust parameters from the scary internet, only allow the white list through.
def pin_params
params.require(:pin).permit(:description)
end
end
Here is my user.rb model code:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :pins
end
Here is my pin.rb model code:
class Pin < ActiveRecord::Base
belongs_to :user
end
And here is the github repo: https://github.com/ModernMeat/pinteresting
Upvotes: 1
Views: 1062
Reputation: 15781
I would suggest you to change order of before_filter
's like this
class PinsController < ApplicationController
before_action :authenticate_user!, except: [:index, :show]
before_action :set_pin, only: [:show, :edit, :update, :destroy]
before_action :correct_user, only: [:edit, :update, :destroy]
because you should first authenticate user with devise and only after that check whether it is correct user.
Upvotes: 2
Reputation: 19039
Look at the error message a bit more closely : "for nil:NilClass"
. This tells you that current_user
is nil
-- which it is indeed, when the user is not logged in.
If you want to make sure the user is logged in to access to the Pins
controller, you can use a before_action
in your controller :
class PinsController < ApplicationController
before_action :authenticate_user!
(authenticate_user!
being a method declared by devise).
Upvotes: 0