Pundit一直要求我登录

时间:2019-01-22 18:06:27

标签: ruby-on-rails pundit

我正在建立一个简单的网站,人们可以在其中上传自己的诗歌并撰写新诗。

我正在尝试使用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>

1 个答案:

答案 0 :(得分:2)

您在ApplicationController中调用before_action :authenticate_user!,因此Devise不允许您看到poetries#index。根本不是Pundit问题。

将此回调从ApplicationController移至所需的控制器,在此您确实要检查身份验证。并用特定的动作来限制它。

class PoetriesController < ApplicationController
  before_action :authenticate_user!, except: [:index, :show]
end
相关问题