정의가 관련에 귀속되는 능력은'신규'에 적용되지 않습니다

7126 단어 cancan

묘사

나의 두 협회
class Step < ActiveRecord::Base
  belongs_to :step_type
  belongs_to :client
end


class StepQuiz < ActiveRecord::Base
   belongs_to :step
   has_many :step_quiz_questions, :dependent => :destroy
   accepts_nested_attributes_for :step
   accepts_nested_attributes_for :step_quiz_questions, :allow_destroy => true
end
나의 능력 수업에서:
can :manage, StepQuiz, :step => {:client_id => user.id}
단계 테스트 컨트롤러의 '새로 만들기' 작업에 접근하려고 시도했을 때 실패했습니다. nil: NilClass의 정의되지 않은 방법인'client id '가 잘못되었습니다.내가 편집을 통해 페이지를 방문할 때, 그것은 정상적으로 작동한다.
나는 사용자가 다른 클라이언트를 위해 테스트를 만드는 것을 방지해야 한다. 그들은 자신의 클라이언트를 위한 테스트만 허용해야 한다.
나는 문제의 발생은 stepquick 대상이 처음 만들어졌을 때 클라이언트 대상이nil이기 때문이라고 생각한다.문제를 해결할 방법이 있습니까?

토론 #1

네, 새로 만들기/만들기 작업에서 권한에 따라 초기 속성을 설정하려고 시도합니다.그러나, 나는 네가 여기에서 한 것처럼 이 삽입 속성의 효과가 어떠한지 확실하지 않다.
반대로 before 필터에서 수동으로 만드는 것이 좋습니다@step_quiz.
나는 내가 할 수 있다고 생각한다.
# in step_quizzes_controller.rb
before_filter :build_step_quiz, :only => [:new, :create]
load_and_authorize_resource
# ...
private

def build_step_quiz
  @step_quiz = StepQuiz.new(params[:step_quiz])
end

You may need to set the client_id in that build_step_quiz method if it's not being set through the params.

토론 #2

I tried doing that to, but I got access denied even though the user_id matched the client_id, can you think of another way to set this up? It is almost like I need to run this on create instead of new.

토론 #셋

I'm not really sure what the problem could be here. Could you try following the steps in Debugging Abilities wiki page? Basically you'll want to create a new StepQuiz exactly the way it is created in the controller - pass the same params to it. Then see if the ability.can? :create, step_quiz. If not, check to make sure the step_quiz.step.client_id matches the user you passed in when creating the ability.

토론 #4

I got it to work, but the problem is client_id doesn't always exist for users (only Clients and ClientAdmin's have a relationship to a specific client). I guess the real problem comes down to the new method as it doesn't have a client.

In my system i have 4 types of users (each if which inherit for a User Model) - SuperAdmin - Has user attributes can do anything in the system. - Client- Has user attributes + an id that represents a "client_id" - ClientAdmin- Has user attributes + which client it is an admin of - Patient- Has user attributes + patient specific attributes such as insurance

Could you explain exactly what happens in the def index method for a StepQuiz based on my ability class?

My code ends up looking like: def build_step_quiz @step_quiz = StepQuiz.new(params[:step_quiz]) @step_quiz.build_step if current_user.is_a?(Client) or current_user.is_a?(ClientAdmin) @step_quiz.step.client_id = current_user.is_a?(Client) ? current_user.id : current_user.client.id end @step_quiz.step_quiz_questions.build end

class Ability
  include CanCan::Ability

  def initialize(user)
    if user.is_a?(SuperAdmin)
      can :manage, :all
    elsif user.is_a?(Client)
      can :read, Client, :id => user.id
      can :manage, ClientAdmin, :client_id => user.id
      can :read, CourseCategory
      can :manage, Course, :client_id => user.id

      #Works because we don't have a "new" method
      can :manage, CourseStep, :course => {:client_id => user.id}
      can :manage, Step, :client_id => user.id

      # Kind of works
      can :manage, StepQuiz, :step =>{:client_id => user.id}

      #Need to change, security issue!!
      can :manage, StepSurvey
      can :manage, StepText
      can :manage, StepDownload
      can :manage, StepVideo
      can :manage, StepPresentation
      ######################
    elsif user.is_a?(ClientAdmin)
      can :read, Client, :id => user.client.id
      can :read, ClientAdmin, :client_id => user.client.id
      can :update, ClientAdmin, :id => user.id
      can :read, CourseCategory
      can :manage, Course, :client_id => user.client.id

      can :manage, Step, :client_id => user.client.id
      #Need to change, security issue!!
      can :manage, StepQuiz
      can :manage, StepSurvey
      can :manage, StepText
      can :manage, StepDownload
      can :manage, StepVideo
      can :manage, StepPresentation
      ######################

    elsif user.is_a?(Patient)
      can [:read, :update], Patient, :id => user.id
    else #Logged out user
      can :create, Patient
    end
  end
end

토론 #5

Could you explain exactly what happens in the def index method for a StepQuiz based on my ability class?


각 디렉터 작동 상황을 보려면 Controller Authorization Example 페이지를 참조하십시오.
색인 작업은 먼저 사용자가 모델 클래스를 읽을 권리가 있는지 확인합니다.이것은 당신의 모든 사례에서 정확합니다. 왜냐하면 당신은

토론 #6

있기 때문입니다.이것은 단지 검사 클래스일 뿐이기 때문에 클라이언트 id를 여기서 검사하지 않습니다.
다음에 can :manage, StepQuiz를 실행하고 데이터베이스 호출을 실행하여 속성 해시와 일치하는 기록을 얻습니다.Client.accessible_by(current_ability) 사용자는 이렇게 합니다.
 load_and_authorize_resource :except => [:new]
 skip_authorization_check :only => [:new]
끝맺다
나는 현재의 능력에 관한 문제가 하나 있다.(: 만들기, 항목)의 속성입니다.각 도 | 키, 값 |
능력 파일에 설정된 모든 속성을 옮겨다니며 @ 프로젝트 대상으로 설정하시겠습니까?
예를 들어,
Category.joins(:step).where(:step => {:client_id => user.id})

As for the new action, you could skip authorization entirely but you probably don't want that. Instead you can just authorize on the class so it doesn't mess with the client_id attribute.

load_and_authorize_resource
skip_authorize_resource :only => :new # this way it still loads the @step_quiz instance

def new
  authorize! :new, StepQuiz
end

토론 #7

Thank you, that gets me the best of both worlds. I have authorization and it is easy to maintain.

토론 #8

For create

def create
@project = Project.new
current_ability.attributes_for(:create, Project).each do |key, value|
  @project.send("#{key}=", value)
end
@project.attributes = params[:project]
authorize! :create, @project
@ 프로젝트 객체에 client id가 설정되어 있습니까?Client

Would the @project object already have the client_id set?


네, 클라이언트 id를 자동으로 설정합니다.이렇게 하면 그것은 권한을 통과할 수 있다.

토론 #9

감사합니다.

좋은 웹페이지 즐겨찾기