# Gemfile
gem 'pundit'
# application_controller.rb
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
include Pundit
protect_from_forgery with: :exception
rescue_from Pundit::NotAuthorizedError do
redirect_to root_url, alert: 'You do not have access to this page'
end
end
# articles/show.html.erb
<%= link_to 'Edit', edit_article_path(@article) if policy(@article).update? %>
<%= link_to 'Delete', article_path(@article), method: :delete if policy(@article).destroy? %>
# policies/article_policy.rb
class ArticlePolicy < ApplicationPolicy
class Scope < Scope
def resolve
scope.where(published: true).or(scope.where(user_id: @user.try(:id)))
end
end
def new? ; user_is_owner_of_record? ; end
def create? ; user_is_owner_of_record? ; end
def show?
user_is_owner_of_record? || @record.published
end
def update? ; user_is_owner_of_record? ; end
def destroy? ; user_is_owner_of_record? ; end
private
def user_is_owner_of_record?
@user == @record.user
end
end
# articles_controller.rb
class ArticlesController < ApplicationController
before_action :authenticate_user!, except: :index
before_action :set_article, only: [:show, :edit, :update, :destroy]
after_action :verify_authorized, except: :index
after_action :verify_policy_scoped, only: :index
def index
# @articles = Article.all
# @articles = Article.where(published: true)
@articles = policy_scope(Article).reverse
end
def show
end
def new
@article = current_user.articles.new
authorize @article
end
def edit
end
def create
@article = current_user.articles.create(article_params)
authorize @article
if @article.save
redirect_to @article, notice: 'Article was successfully created.'
else
render :new
end
end
def update
if @article.update(article_params)
redirect_to @article, notice: 'Article was successfully updated.'
else
render :edit
end
end
def destroy
@article.destroy
redirect_to articles_url, notice: 'Article was successfully destroyed.'
end
private
def set_article
@article = Article.find(params[:id])
authorize @article
end
def article_params
params.require(:article).permit(:title, :user_id, :content, :published)
end
end