2011-08-22 2 views
1

CanCan을 사용합니다.N 부모 리소스 중 하나가 존재해야하는 RESTful 컨트롤러를 작성하려면 어떻게해야합니까?

POST /books/123/loans  # LoansController#new :book_id  => 123 
POST /magazines/456/loans # LoansController#new :magazine_id => 456 

BooksMagazines는 부모 클래스 Stockable, 그래서 위의 정보는 다음의 제품에 해당합니다 : 도서관 응용 프로그램으로, Book 또는 Magazine은 체크 아웃 할 수

POST /stockables/123/loans # LoansController#new :stockable_id => 123 
POST /stockables/456/loans # LoansController#new :stockable_id => 456 

그러나 모든 Stockable 수 대여 됨 :

# error: can't check out reference books from the library 
POST /reference_books/789/loans # LoansController#new :reference_book_id => 789 

# same error 
POST /stockables/789/loans  # LoansController#new :stockable_id  => 789 

옳은 방법은를 작성하는 것입니다.CanCan을 사용하면 Loanable의 모든 경로를 만들지 않고도 Loanable 인 모든 것을 처리 할 수 ​​있습니까?

답변

0

각 작업 유형에 대해 어떤 작업이 허용되는지/허용되지 않는지 정의하려면 ability.rb을 사용합니다. 다음은 STI를 사용 중이라고 가정하므로 db에 각 행이 나타내는 클래스 이름이 포함 된 stockable_type 열이 있습니다. STI를 사용하지 않는다면 해시 구문 [CanCan wiki 확인, 자세한 내용은 Defining Abilities] 대신 블록을 cancannot 메소드에 전달하여 다른 유형의 메소드를 올바르게 사용할 수 있습니다.

class Ability 
    include CanCan::Ability 

    def initialize(user) 
    user ||= User.new # guest user (not logged in) 
    can [:read], :all 
    can :new, Loan, :stockable_type => ["Book", "Magazine"] 
    cannot :new, Loan, :stockable_type => "ReferenceBook" 
    end 
end 

그런 다음, 당신의 LoansControllerCanCan::AccessDenied을 잡을 당신은 참고 도서를 체크 아웃을 시도하는 사람들을 리디렉션 할 수 있습니다.

rescue_from CanCan::AccessDenied do |exception| 
    redirect_to some_url, :alert => "You can't check out reference books!" 
end 
+0

매우 해결책이 아닌 자동으로 고장난 경로 ('POST/reference_books/123/loans')가 계속 노출되므로이 해결책이 마음에 들지 않습니다. –

+0

routes.rb가'/ reference_books/: id/loans'를 노출했다면 실제로 질문 한 것과 관련이 없다는 사실이 아닙니까? 'LoansController'를 작성하여 부서진 경로를 노출시키지 않도록 할 방법이 없습니다. 그것들은 완전히 별개의 서브 시스템입니다 (당신이 알고 있다고 확신합니다). –

관련 문제