Я создаю простой сайт, где люди могут загружать свои стихи и писать новые.
Я пытаюсь использовать Pundit, чтобы:
- Каждый может увидеть все стихи / стихи (в указателе)
- Только вошедший в систему пользователь может создавать стихи
- Только пользователь, создавший стихи, может обновить ИЛИ удалить его
Я следовал официальным документам, но мне все еще нужно войти, чтобы выполнить какое-либо действие в моем контроллере.
Я не уверен, что я делаю неправильно, так как я слежу за документацией, и мне кажется, что это копирование / вставка.
Мой код:
poetries_controller.rb
class PoetriesController < ApplicationController
before_action :set_poetry, only: [:show, :edit, :update, :destroy]
def index
@poetries = policy_scope(Poetry).order("RANDOM()").limit(30)
end
def show
end
def new
@poetry = Poetry.new
authorize @poetry
end
def create
Poetry.create(poetry_params)
authorize @poetry
redirect_to poetries_path
end
def edit
end
def update
@poetry.save
redirect_to poetry_path(@poetry)
end
def destroy
@poetry.destroy
redirect_to poetries_path
end
private
def poetry_params
params.require(:poetry).permit(:title, :author, :body)
end
def set_poetry
@poetry = Poetry.find(params[:id])
authorize @poetry
end
end
application_controller.rb
class ApplicationController < ActionController::Base
include Pundit
protect_from_forgery with: :exception
before_action :authenticate_user!
after_action :verify_authorized, :except => :index, unless: :devise_controller?
after_action :verify_policy_scoped, :only => :index, unless: :devise_controller?
rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
private
def user_not_authorized
flash[:alert] = "Non sei autorizzato a eseguire questa azione"
redirect_to(root_path)
end
end
poetry_policy.rb
class PoetryPolicy < ApplicationPolicy
class Scope < Scope
def resolve
scope.all
end
end
def show?
true # Anyone can view a poetry
end
def create?
true # Anyone can create a poetry
end
def update?
record.user == user # Only poetry creator can update it
end
def destroy?
record.user == user # Only poetry creator can update it
end
end
application_policy.rb
class ApplicationPolicy
attr_reader :user, :record
def initialize(user, record)
@user = user
@record = record
end
def index?
false
end
def show?
scope.where(:id => record.id).exists?
end
def create?
false
end
def new?
create?
end
def update?
false
end
def edit?
update?
end
def destroy?
false
end
def scope
Pundit.policy_scope!(user, record.class)
end
class Scope
attr_reader :user, :scope
def initialize(user, scope)
@user = user
@scope = scope
end
def resolve
scope.all
end
end
end
index.html.erb
<div class="container">
<div class="row">
<% @poetries.each do | poetry| %>
<div class="col-xs-12 col-sm-4">
<% if policy(poetry).show? %>
<%= link_to poetry_path(poetry) do %>
<div class="card">
<div class="card-description">
<h2> <%=poetry.title=%> </h2>
<% a = sanitize(poetry.body.truncate(170), tags: %w(br)) %></p>
<p> <%= a %></p>
<p><i><%=poetry.author=%><i></p>
</div>
</div>
<% end %>
<% end %>
</div>
<% end %>
<!-- </div> -->
</div>
</div>