代码之家  ›  专栏  ›  技术社区  ›  rld

具有权威gem的类别策略规范的问题

  •  0
  • rld  · 技术社区  · 7 年前

    所以我通过分类来关联类别和帖子。 我正试图限制权威gem的访问权限,并使用RSpec进行测试,以便按类别显示帖子。因为有了这个联想,我有了这样的东西: c=类别。第一 c、 职位

    我按类别显示帖子。

    我需要一些帮助。

    my categories\u控制器。rb型

    class CategoriesController < ApplicationController
      before_action :set_category, only: [:show]
    
      def show
        authorize @category, :show?
      end
    
      private
    
      def set_category
        @category = Category.find(params[:id])
      end
    end
    

    类别rb型

    class Category < ActiveRecord::Base
      has_many :categorizations, dependent: :destroy
      has_many :posts, through: :categorizations
    
      validates :name,
                      presence: true,
                      length: { minimum: 3, maximum: 30 },
                      uniqueness: true
    end
    

    应用程序/视图/类别/显示。html。苗条的

    = title("Category - #{@category.name}")
    #category.text-center
      h1 Category: <small>#{@category.name}</small>
    
      - if @category.posts
        #category.posts
          - @category.posts.each do |post|
            .row.col-md-12
              .caption
                h2 = link_to post.title, post
                p = link_to post.subtitle, post
                small = "by : #{post.author}"
              hr
    

    路线。rb型

    Rails.application.routes.draw do
    
      namespace :admin do
        root 'application#index'
    
        resources :posts, only: [:new, :create, :destroy]
        resources :categories
    
        resources :users do
          member do
            patch :archive
          end
        end
      end
    
      devise_for :users
    
      root "posts#index"
    
      resources :posts, only: [:index, :show, :edit, :update]
      resources :categories, only: [:show]
    end
    

    category\u策略。rb型

    class CategoryPolicy < ApplicationPolicy
      class Scope < Scope
        def resolve
          resolve
        end
      end
    
      def show?
        user.try(:admin?) || record.post.has_member?(user)
      end
    end
    

    category\u policy\u spec.rb类别

    require 'rails_helper'
    
    RSpec.describe CategoryPolicy do
      context "permissions" do
        subject        { CategoryPolicy.new(user, category) }
        let(:user)     { create(:user) }
        let(:post)     { create(:post) }
        let(:category) { create(:category) }
    
        context "for anonymous users" do
          let(:user) { nil }
    
          it { should_not permit_action :show }
        end
    
        context "for viewers of the post" do
          before { assign_role!(user, :viewer, post) }
    
          it { should permit_action :show }
        end
    
        context "for editors of the post" do
          before { assign_role!(user, :editor, post) }
    
          it { should permit_action :show }
        end
    
        context "for managers of the post" do
          before { assign_role!(user, :manager, post) }
    
          it { should permit_action :show }
        end
    
        context "for managers of other posts" do
          before do
             assign_role!(user, :manager, create(:post))
          end
    
          it { should_not permit_action :show }
        end
    
        context "for administrators" do
          let(:user) { create(:user, :admin) }
    
          it  { should permit_action :show }
        end
      end
    end
    

    我在用这个火柴。 pundit\u matcher。rb型

    RSpec::Matchers.define :permit_action do |action|
      match do |policy|
        policy.public_send("#{action}?")
      end
    
      failure_message do |policy|
        "#{policy.class} does not allow #{policy.user || "nil"} to " +
          "perform :#{action}? on #{policy.record}."
      end
    
      failure_message_when_negated do |policy|
        "#{policy.class} does not forbid #{policy.user || "nil"} from " +
          "performing :#{action}? on #{policy.record}."
      end
    end
    

    邮递rb型

    class Post < ActiveRecord::Base
      belongs_to :author, class_name: "User"
      has_many :roles, dependent: :delete_all
      has_many :categorizations, dependent: :destroy
      has_many :categories, through: :categorizations
    
      mount_base64_uploader :attachment, AttachmentUploader
    
      validates :title,
                  presence: true,
                  length: { minimum: 10, maximum: 100 },
                  uniqueness: true
      validates :subtitle,
                  length: { maximum: 100 }
      validates :content,
                  presence: true,
                  length: { minimum: 30 }
      validates :attachment, file_size: { less_than: 1.megabytes }
    
    
      def has_member?(user)
        roles.exists?(user_id: user)
      end
    
      [:manager, :editor, :viewer].each do |role|
        define_method "has_#{role}?" do |user|
          roles.exists?(user_id: user, role: role)
        end
      end
    
    end
    

    roler。rb型

    class Role < ActiveRecord::Base
      belongs_to :user
      belongs_to :post
    
      def self.available_roles
        %w(manager editor viewer)
      end
    end
    

    当我尝试运行时:

    rspec spec/policies/category_policy_spec.rb
    

    我收到以下错误:

    Failure/Error: user.try(:admin?) || record.post.has_member?(user)
    
         NoMethodError:
           undefined method `post' for #<Category:0x007fc61bfdbf40>
           Did you mean?  posts
    

    可以在节目中按类别显示这些帖子,或者我需要切换到索引?

    1 回复  |  直到 7 年前
        1
  •  1
  •   Thomas Walpole    7 年前

    正如错误所述,您的类别模型没有 post 方法,它只有 posts . 这是因为Category有许多帖子。正因为如此 record.post.has_member?(user) 在您的类别中,策略没有任何意义( record 是类别实例)。因为类别似乎与用户没有直接关系,而您的角色与用户和帖子相关联。

    我不清楚你的分类策略的真正目的是什么,除非它只允许用户在已经有使用该分类的帖子的情况下查看分类?如果是这种情况,那么您需要更改策略,以实际检查是否存在这些策略。