2016-09-26 38 views
0

感謝您的閱讀!在我的應用中實現用戶角色的方式

我目前的工作在我的新的應用程序,並尋找最好的方式來實現一個功能

通過情景我需要實現

我「作爲一個用戶的位置有作用」已完成:

場景: 當用戶將新位置添加到配置文件 其中一個需要的字段是「角色」。這可能是「客人」,「經理」或「賣家」。在模型方面完成他的最好方法是什麼?

我做到了這一點與has_many_through assosiation

控制器:

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 

機型:

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 

=====

問: 你可以建議更多beatiful方式實現他的功能?

+1

可以將用戶在不同的地點不同的角色?如果是的話,通過關聯來管理是正確的。但是,並不是只保留通過表的每個記錄中的角色名稱。製作一個角色表和相應的角色模型,並通過表格添加一個關聯。 –

+1

我看到你有3個不同的領域,每個角色一個。看,這可能很糟糕,因爲無論何時定義新角色,您都必須向模型添加新字段。相反,您應該保留單個字段「角色」並將「客人」,「經理」或「賣家」保存在其中。 –

+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)相結合,該授權庫定義了有關角色執行什麼操作並強制執行這些規則的規則。

+0

非常感謝!我會以這種方式實施 – Art

相關問題