Rails策略(Pundit)链接仅显示user.admin?

时间:2015-06-17 19:56:15

标签: ruby-on-rails authorization pundit

所以我的政策有问题。当用户创建主题时,他们应该能够看到该主题的编辑和删除按钮,但是这些按钮没有显示。但是,如果用户的角色定义为管理员,那么他们实际上可以看到编辑和删除主题按钮。

希望对此有所了解:

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?
    user.present?
  end

  def new?
    create?
  end

  def update?
    user.present? && (record.user == user || user.admin?)
  end

  def edit?
    update?
  end

  def destroy?
    update?
  end

  def scope
    record.class
  end

  class Scope
    attr_reader :user, :scope

    def initialize(user, scope)
      @user = user
      @scope = scope
    end

    def resolve
      scope
    end
  end
end

topic_policy.rb

class TopicPolicy < ApplicationPolicy
  def index?
    true
  end
end

user.rb (的模型):

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable, :confirmable

  mount_uploader :avatar, AvatarUploader
  has_many :topics, dependent: :destroy
  has_many :bookmarks, dependent: :destroy
  has_many :likes, dependent: :destroy

  validates :name, presence: true

  def admin?
    role == 'admin'
  end

  def moderator?
    role == 'moderator'
  end

  def member?
    role == 'member'
  end

  def liked(bookmark)
    likes.where(bookmark_id: bookmark.id).first
  end
end

最后,这是展示视图的一大块,其中包含按钮:

<div class="row landing-top">
  <h1 class="lato-dark text-center"><%= topic_hash %></h1>
  <div class="col-md-2 text-center">
    <%= link_to topics_path, class: 'btn btn-default btn-sm' do %>
        <span class="glyphicon glyphicon-circle-arrow-left black inliner"></span>
        <h5 class="inliner lato-dark">Back to Topics</h5>
    <% end %>
  </div>
  <div class="col-md-8">
    <div class="js-bookmarks">
      <%= render partial: 'bookmarks/bookmark', collection: @bookmarks %>
    </div>
  </div>
  <div class="col-md-2">
    <div class="text-center">
      <% if policy(@topic).update? %>
      <!-- Button trigger modal -->
        <button type="button" class="btn button-3d-edit" data-toggle="modal" data-target="#edit">
          <span class="glyphicon glyphicon-pencil"></span>
          Edit Topic
        </button>
      <% end %>
      <% if policy(@topic).destroy? %>
        <%=link_to @topic, method: :delete, class: 'btn button-3d-delete', data: { confirm: 'Are you sure you want to delete this topic?' } do %>
          <span class="glyphicon glyphicon-remove"></span>
          Delete Topic
        <% end %>
      <% end %>
      <% if policy(@bookmarks).create? %>
      <!-- Button trigger modal -->
        <button type="button" class="btn button-3d" data-toggle="modal" data-target="#new-bookmark">
          <span class="glyphicon glyphicon-plus"></span>
          New Bookmark
        </button>
      <% else %>
        <button type="button" class="btn button-3d" data-toggle="modal" data-target="#notSignedIn">
          <span class="glyphicon glyphicon-plus"></span>
          New Bookmark
        </button>
      <% end %>
    </div>
  </div>
</div>

1 个答案:

答案 0 :(得分:0)

因此,在试图欺骗我的过程中,我找到了答案。正在使用user_id nil创建主题,这就是为什么Pundit无法跟踪特定主题是否由特定用户创建的原因。

因此,在我的topics_controller文件中,我添加了@topic.user = current_user,然后开始为创建的主题设置user_id,允许Pundit跟踪创建该特定主题的人。

def create
    @topic = Topic.new(topic_params)
    @topic.user = current_user
    @new_topic = Topic.new
    authorize @topic
    if @topic.save
      flash[:notice] = "Topic was created successfully."
    else
      flash[:error] = "There was an error creating your topic. Please try again."
    end

    respond_to do |format|
      format.html
      format.js
    end
  end