هل يجب أن أتخطى التفويض ، مع كانكان ، عن إجراء يقوم بتثبيت مورد؟

StackOverflow https://stackoverflow.com/questions/2831720

  •  26-09-2019
  •  | 
  •  

سؤال

أنا أكتب تطبيق ويب لاختيار قوائم بطاقات عشوائية من مجموعات أكبر من البطاقات. لدي طراز بطاقة وطراز بطاقة. يحتوي كلا النموذجين على مجموعة كاملة من 7 إجراءات (: الفهرس ،: جديد ،: إظهار ، إلخ). لدى CardseStsController إجراء إضافي لإنشاء مجموعات عشوائية: :random.

# app/models/card_set.rb
class CardSet < ActiveRecord::Base
  belongs_to :creator, :class_name => "User"
  has_many :memberships
  has_many :cards, :through => :memberships

# app/models/card.rb
class Card < ActiveRecord::Base
  belongs_to :creator, :class_name => "User"
  has_many :memberships
  has_many :card_sets, :through => :memberships

لقد أضفت ابتكار للمصادقة و cancan للتصريحات. لدي مستخدمون يحملون دور "محرر". يُسمح للمحررين بإنشاء بطاقات جديدة. يمكن لمستخدمي الضيوف (المستخدمين الذين لم يسجلوا الدخول) استخدام فقط :index و :show أجراءات. هذه التراخيص تعمل كما تم تصميمها. يمكن للمحررين حاليًا استخدام كل من :random و ال :new الإجراءات دون أي مشاكل. مستخدمي الضيوف ، كما هو متوقع ، لا يمكن.

# app/controllers/card_sets_controller.rb
class CardSetsController < ApplicationController
  before_filter :authenticate_user!, :except => [:show, :index]
  load_and_authorize_resource

أريد أن أسمح لمستخدمي الضيوف باستخدام :random العمل ، ولكن ليس :new عمل. بمعنى آخر ، يمكنهم رؤية مجموعات عشوائية جديدة ، ولكن لا ينقذها. زر "حفظ" على :random عرض Action مخفي (كما هو مصمم) من مستخدمي الضيوف. المشكلة هي ، أول شيء :random الإجراء هو إنشاء مثيل جديد لنموذج CardSet لملء العرض. عندما يحاول كانكان ذلك load_and_authorize_resource بطاقة بطاقة جديدة ، ترمي استثناء كانان :: Accessdenied. لذلك ، لا يتم تحميل العرض أبدًا ويتم تقديم رسالة "تحتاج إلى تسجيل الدخول أو التسجيل قبل المتابعة".

# app/controllers/card_sets_controllers.rb
def random
  @card_set = CardSet.new( :name => "New Set of 10", :set_type => "Set of 10" )

أدرك أنه يمكنني القول load_and_authorize_resource لتخطي :random العمل بالمرور :except => :random للمكالمة ، لكن هذا يشعر فقط "خاطئ - ظلم - يظلم" لسبب ما.

ما هو "حقا" طريقة للقيام بذلك؟ هل يجب أن أقوم بإنشاء مجموعة عشوائية جديدة دون إنشاء إنشاء بطاقة جديدة؟ هل يجب أن أمضي قدمًا وأضف الاستثناء؟

تحديث

لم أقم بتضمين فصل قدرتي أعلاه. لقد قمت بتحديثه لتضمين الإجراء ": عشوائي" ، لكنه لا يزال لا يعمل بشكل صحيح.

class Ability
  include CanCan::Ability

  def initialize( user )
    user ||= User.new # User hasn't logged in

    if user.admin?
      can :manage, :all if user.admin?
    else
      # All users, including guests:
      can :read, [Card, CardSet]
      can :random, CardSet

      # All users, except guests:
      can :create, [Card, CardSet] unless user.role.nil?
      can :update, [Card, CardSet] do |c|         
        c.try( :creator ) == user || user.editor?
      end

      if user.editor?
        can [:create, :update], [Card, CardSet]
      end
    end
  end
end
هل كانت مفيدة؟

المحلول

لقد وجدت مشكلتي. لم يكن كانسان القضية على الإطلاق! كان السطر التالي في وحدة تحكم CardSet الخاصة بي هو رمي الاستثناء وإعادة توجيه ضيفتي (لم يتم تسجيل الدخول) إلى صفحة تسجيل الدخول:

before_filter :authenticate_user!, :except => [:show, :index]

لقد غيرتها لقراءة:

before_filter :authenticate_user!, :except => [:show, :index, :random]

والآن يعمل الرمز على النحو المقصود: يمكن لمستخدمي الضيوف عرض المجموعات العشوائية الجديدة التي تم إنشاؤها ، لكن لا يمكنهم "حفظها" إلا إذا قاموا بتسجيل الدخول لأول مرة.

لذلك ، كانت مشكلتي الحقيقية مع ابتكار (أو ، في الواقع ، تكوين ابتكار) وليس مع كانكان على الإطلاق.

نصائح أخرى

حسنًا ، سيكون الشيء الصحيح هو استخدام فئة القدرة Cancan لتحديد قواعد التفويض الصحيحة.

في القدرة

  def initialize(user)
#everyone
    can [:read, :random], [CardSet]
#everyone who is editor
    if user.editor?
      can [:new, :create], [CardSet]

إلخ

المشكلة هي أن أول شيء: الإجراء العشوائي هو إنشاء مثيل جديد لنموذج CardSet لملء العرض. عندما يحاول Cancan تحميل _Anuthorize_resource بطاقة بطاقة جديدة ، فإنه يلقي استثناءً من cancan :: accessdenied.

بينما يسمح Cancan بإجراء وحدة التحكم ، فإن إنشاء مثيل جديد في إجراء عشوائي (IE CardSet.new) ليس في نطاق Cancan. ربما تحصل على الخطأ لأنه ليس لديك قواعد محددة في القدرة. rb للعمل العشوائي. مثالي أعلاه يجب أن يحل مشكلتك

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top