AHmed AHmed - 2 months ago 24
Ruby Question

Rails: undefined method `user' for nil:NilClass (NoMethodError in ArticlesController#destroy)

When i try to delete an article in my app i get this error although there is an association between the users and the articles and the current user is logged in Here's my code

articles_controller.rb

class ArticlesController < ApplicationController
before_action :require_user , except:[:index,:show]
before_action :same_user , only: [:edit,:update,:destroy]

def index
@articles = Article.all
end

def new
@article = Article.new
end


def create
@article = current_user.articles.build(article_params)

if @article.save
flash[:notice] = "Your Article was Created"
redirect_to article_path(@article)
else
render 'new'
end
end

def show
@article = Article.find(params[:id])
end

def edit
@article = Article.find(params[:id])
end

def update
@article = Article.find(params[:id])
if @article.update(article_params)
flash[:notice] = "Your Article was Updated"
redirect_to article_path(@article)
else
render 'edit'
end

end

def destroy
@article = Article.find(params[:id])
@article.destroy
flash[:notice] = "Your Article was deleted"
redirect_to articles_path(@article)
end

private

def article_params
params.require(:article).permit(:title,:description, category_ids:[])
end

def same_user
if current_user != @article.user and !current_user.admin?
flash[:danger] = "Your are not allowed"
redirect_to root_path
end
end


end

_article.html.erb

<% obj.each do |article|%>
<%= article.title%><br>
<%= article.description%>
<%= link_to "Show", article_path(article)%>
<% if article.categories.any?%>
<%= render article.categories%>
<%end%>
<% if logged_in? && current_user == article.user || current_user.try(:admin?) # Another way to check for the user current_user.admin?
%>
<%= link_to "Edit", edit_article_path(article)%>
<%= link_to "Delete", article_path(article), method: :delete, data: {confirm: "Really delete this article?"} %>
<%end%>
<small>Created By <%= article.user.email %></small>

<%end%>


application_controller.rb

class ApplicationController < ActionController::Base
protect_from_forgery with: :exception

helper_method :current_user , :logged_in?

def current_user
@current_user ||= User.find(session[:user_id]) if session[:user_id]
end
end


def logged_in?
!!current_user
end

def require_user
if !logged_in?
flash[:danger] = "Please check your info"
redirect_to articles_path
end
end

Answer

add this line as first in your same_user method:

@article = Article.find(params[:id])

You should define your @article variable in same_user because you add this method to before_action, this metod will be trigerred before method delete. You tried refer to variable, which was defined later.