2016-09-26 2 views
0

읽어 주셔서 감사합니다!내 앱에서 사용자 역할을 구현하는 편리한 방법

나는 현재 내가 구현해야

무엇 I "사용자 A와 위치에서 역할을"다음 기능을 시나리오에 의해

을 구현하기 위해 나의 새로운 응용 프로그램에 노력하고 최선의 방법을 찾고 있어요

수행 완료 :

시나리오 : 사용자가 프로필에 새 위치를 추가하면 요청 된 필드 중 하나가 "역할"입니다. 그것은 "게스트", "매니저"또는 "판매자"일 수 있습니다. 모델 측면에서 그의 목표를 달성하는 가장 좋은 방법은 무엇입니까?

def create 
    @location = Location.new(location_params) 
    @location.profiles << current_user.profile 
    #set user role 
    current_user.profile.profile_location_throughs.where(location_id: location.id).set_role(params[:location][:role]) 
    respond_to do |format| 
     if @location.save 
     .... 
     end 
    end 
end 

모델 : :

나는 has_many_through의 assosiation와

CONTROLLER이 달성 당신이 더 아름 다운 방법을 제안 할 수 :

class Profile < ActiveRecord::Base do 
    has_many :profile_location_throughs 
    has_many :locations, through: :profile_location_throughs 
end 

class Location < ActiveRecord::Base do 
    has_many :profile_location_throughs 
    has_many :locations, through: :profile_location_throughs 
end 

class ProfileLocationThrough < ActiveRecord::Base 
    # with boolean fields: manager, seller, guest 

    belongs_to :location 
    belongs_to :profile 

    def set_role(role) 
    case role 
     when "guest" 
     self.guest = true 
     when "seller" 
     self.seller = true 
     when "manager" 
     self.manager = true 
    end 
    end 

end 

=====을 질문

그의 기능을 구현하려면?

+1

캔 사용자는 서로 다른 위치에서 다른 역할을 가지고? 그렇다면 연관을 통해 관리하는 것이 옳습니다. 하지만, 대신 테이블을 통해 각 레코드의 역할 이름을 유지. 'roles' 테이블과 각각의'Role' 모델을 만들고이를 통해 테이블에 연관을 추가하십시오. –

+1

각 역할마다 하나씩 3 개의 다른 필드가 있음을 확인했습니다. 새 역할이 정의 될 때마다 모델에 새 필드를 추가해야하기 때문에 상황이 좋지 않을 수 있습니다. 대신에 싱글 필드'role'을 유지하고 그 안에 "guest", "manager"또는 "seller"를 저장해야합니다. –

+0

예. 한 위치에서 "판매자", 다른 "게스트"등등이 될 수 있습니다. – Art

답변

2

역할 기반 인증을 수행하는 방법에는 여러 가지가 있습니다.

가장 간단한 방법은 스스로 사용자에게 enum를 추가하는 것입니다 :

class Profile < ApplicationRecord 
    enum role: [:guest, :seller, :manager] 
end 

이 꽤 그것은 단지 "글로벌"역할 허용하는 비록 제한됩니다. 리소스 범위 역할을 원할 경우 조인 테이블이 필요합니다.

class Profile < ApplicationRecord 
    has_many :roles 
    has_many :locations, through: :roles 

    def has_role?(role, location = nil) 
    self.roles.exists?({ name: role, location: location}.compact) 
    end 

    def add_role(role, location) 
    self.roles.create!({ name: role, location: location }) 
    end 
end 

class Role < ApplicationRecord 
    belongs_to :profile 
    belongs_to :location 
end 

class Location < ApplicationRecord 
    has_many :roles 
    has_many :profiles, through: :roles 
end 

이 예에서는 단순히 roles.name 열의 문자열을 사용하고 있습니다. 역할의 종류가 제한되어 있으면 enum을 사용할 수도 있습니다. 서로 다른 종류의 리소스에서 역할을 범위 지정하기 위해 동일한 역할 모델 (말장난 없음)을 사용하려는 경우 polymorphic belongs_to relationship을 사용할 수 있습니다.

class Role < ApplicationRecord 
    belongs_to :profile 
    belongs_to :resource, polymorphic: true 
end 

class Location < ApplicationRecord 
    has_many :roles, as: :resource 
    has_many :profiles, through: :roles 
end 

class OtherThing < ApplicationRecord 
    has_many :roles, as: :resource 
    has_many :profiles, through: :roles 
end 

역할은 인증 솔루션의 일부일뿐입니다. 이 역할을 Pundit 또는 CanCanCan과 같은 권한 부여 라이브러리와 결합하면 어떤 역할이 무엇을 할 것인지에 대한 규칙을 정의하고 이러한 규칙을 시행 할 수 있습니다.

+0

고마워요! 나는 그런 방식으로 구현할 것이다. – Art

관련 문제