2015-01-22 1 views
0

일반 사용자는 변경할 수 없지만 관리자는 허용해야하는 속성이있는 여러 모델이 있습니다. 예를 들어 (내 문제 도메인이 아니지만) 일반 사용자는 Postuser_id을 변경할 수 없어야하지만 관리자는이를 허용해야합니다.관리자 계정에 대한 추가 매개 변수 허용

보기 수준에서이 작업을 처리하는 것은 간단합니다. 사용자가 관리자인지 여부에 따라 필드를 표시할지 여부를 표시 할 수 있지만 컨트롤러의 강력한 매개 변수 처리 방법으로 처리하는 방법을 모르겠습니다.

def post_params 
    if admin? 
    params.require(:post).permit(:title, :text, :date, :user_id) 
    else 
    params.require(:post).permit(:title, :text, :date) 
end 
end 

이 처리하는 더 좋은 방법이 있나요 : 나는 (그리고 솔루션 offered previously)와 함께 올 수있는 유일한 해결책은, 당신이하지 레일에 수행하려고 뭔가를 자신을 반복하는 것입니다?

답변

0

나쁜 사용자를 방지하기 위해 두 개의 다른 매개 변수 목록을 검색 할 필요가 없습니다. 대신에 cancan 보석 사용을 고려해야합니다.

(사용자 역할과 상관없이) 단일 매개 변수 목록을 일관되게 사용합니다. (사용자 역할을 기반으로) 당신의 행동 보호/제한하려면 그시

, cancan gem.

가 ability.rb 파일에 각 역할의 권한을 정의 사용해보십시오.

#ability.rb 

class Ability 
    include CanCan::Ability 

    def initialize(user) 
    user ||= User.new 

    if user.is?(:Administrator) # Access for Admin user 
     can :access, :all 
    elsif user.is?(:"Finance Manager") #Access for Finance Manager 
     can :access, [:subjects, :researchsubjects, :visits, :sessions] 
    elsif user.is?(:"Research Director") # Access for Research Director 
    else 
     #do something 
    end 
    end 
end 

더 많은 정보를 원하시면, cancan gem을 확인하시기 바랍니다 : 같은

샘플 기능 파일을 찾을 것입니다.

+0

Cancan은 컨트롤러 작업 및 모델 작업에 대한 액세스를 제한하는 멋진 보석입니다. 사용자 입력을 제한하기 위해 강력한 매개 변수와 함께 코드를 사용하는 방법에 대한 코드를 제공 할 수 있습니까? – BroiSatse

1

현재 구현에 문제가없는 것으로 보입니다. 즉, 다른 컨트롤러 (예 : Api :: PostsConrtoller)에서 이러한 속성 권한을 다시 사용하려면 DRY하는 한 가지 방법은 자체 클래스에 코드를 추출하는 것입니다. Ryan Bates가 Railscast about Strong Parameters에 사용하는 방법입니다 (참고 : Pro 계정 필요).

# app/models/permitted_params.rb 

class PermittedParams < Struct.new(:params, :user) 
    def post 
    if user && user.admin? 
     params.require(:post).permit(:title, :text, :date, :user_id) 
    else 
     params.require(:post).permit(:title, :text, :date) 
    end 
    end 
end 

그런 다음 ApplicationController

# app/controllers/application_controller.rb 

def permitted_params 
    @permitted_params ||= PermittedParams.new(params, current_user) 
end 

내에서이 클래스를 인스턴스화 한 다음 논리를 복제하지 않고 해당 권한 로직을 필요로하는 어떤 컨트롤러를 사용할 수 있습니다. 이 솔루션에 대해 정말 좋은 무엇

# app/controllers/posts_controller.rb 

def update 
    @post = Post.find(params[:id]) 
    if @post.update_attributes(permitted_params.post) 
    ... 
    else 
    ... 
    end 
end 

당신은 또한 건조까지 귀하의 의견을 약간 PermittedParams 클래스를 수정하여 사용할 수 있다는 것입니다.

# app/models/permitted_params.rb 

class PermittedParams < Struct.new(:params, :user) 
    def post 
    params.require(:post).permit(*post_attributes) 
    end 

    def post_attributes 
    if user && user.admin? 
     [:title, :text, :date, :user_id] 
    else 
     [:title, :text, :date] 
    end 
    end 
end 

및 뷰 도우미로서 permitted_params 방법을 노출한다.

# app/controllers/application_controller.rb 

def permitted_params 
    @permitted_params ||= PermittedParams.new(params, current_user) 
end 
helper_method :permitted_params 

마지막으로 양식 필드를 표시하거나 숨기려면보기에서 사용하십시오.

# app/views/posts/edit.html.erb 

<% if permitted_params.post_attributes.include? :user_id %> 
# show the user_id field 
<% end %> 
0

나는 이전 답변에 만족하지 않았습니다.내가 정말로하고 싶었던 것은 다음과 같습니다.

params.require(:post).permit(:title, :text, :date, user_id: admin?) 

저는 그렇게하기로 결정했습니다. 우선은 레일 핵심 패치를했지만, 그들은 패치를 수락에 관심이 있었다 :

이 API는 진화 할 수 그것은 손에서 쉽게 얻을 수있는 몇 가지 방향이있다, 섬세, 일관성 , 또는 확장 기능을 확장하기위한 기대치를 창출하십시오 ... 우리는 지금 그대로 유지하는 것을 선호합니다.

일반적으로 일반 프로그래밍에서 API를 직접 지원하지 않는 사례를 선호합니다. 이 경우,

pkeys = [:title, :body] 
pkeys << :author_id if admin? 
params.require(:post).permit(*pkeys) 

또는 라인에 뭔가 (당신은 이미 물론 가능했다 알았지 만, 그냥 예를 가진 점을 설명하기 위해) 할 것이다.

그래서 나는 turned it into a gem instead입니다. 나는 그것을 유지하고 싶습니다. 이 기능은 필자가 작성한 모든 Rails 응용 프로그램의 일부가 아니지만 적어도 필자는 Gemfile에서 가져올 수 있습니다.

gem 'rails_conditional_params'