2016-09-26 7 views
0

読んでいただきありがとうございます!私が実装する必要が私のアプリでユーザーの役割を実装する便利な方法

私は現在、私の新しいアプリに取り組んでおり、シナリオでは、次の機能に

を実施するための最良の方法を探している「ユーザーAとしては、場所での役割を持っている」

WHAT I HAVE DONE:

シナリオ: ユーザーがプロファイルに新しい場所を追加すると、 必須フィールドの1つが「ロール」です。それは「ゲスト」、「マネージャー」、または「売り手」になる可能性があります。モデル側で彼を達成する最善の方法は何ですか?

私はhas_many_through assosiationで

CONTROLLERこれを達成:

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 

MODELS:

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 

=====

QUESTION: は、あなたがより美しい道を提案でしたが彼の機能を実装する?

+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列の文字列を使用しています。ロールの種類に制限がある場合は、列挙型を使用することもできます。同じ種類のロールモデルを使用したい場合は、 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 

役割は認証ソリューションの一部に過ぎないことに注意してください。これをPunditCanCanCanのような認可libと組み合わせて、どの役割が何をしてそれらの規則を実施するかに関する規則を定義します。

+0

ありがとう!私はそのような方法で実装するだろう – Art

関連する問題