2014-09-02 72 views
2

我被困在以下問題 - 我懷疑有一個簡單的解決方案,但我無法弄清楚。Rails 4 |使用位掩碼|將表單中的角色分配給用戶RoleModel

我使用Role Model Gem使用Rails 4

一切運作良好,並已分配的角色存儲完美地在用戶模型內部位掩碼的roles_mask屬性(整數)。

現在,我希望管理員可以分配以及通過FORM(視圖)從用戶刪除角色。我不是Rails Ninja,所以可能有一個技巧來做到這一點。

根據該文件,我可以做到以下幾點:

# role assignment 
>> u.roles = [:admin] # ['admin'] works as well 
=> [:admin] 

# adding roles (remove via delete or re-assign) 
>> u.roles << :manager 
=> [:admin, :manager] 

這樣理解。

而我的方法是查詢表格中的所有有效角色:

# get all valid roles that have been declared 
>> User.valid_roles 
=> [:admin, :manager, :author] 

然後列出他們的複選框。一旦表單被提交,我分配/刪除角色。

問題: 這是正確的方法,這是否甚至工作,如果是的話,如何?

+0

我通過引入attr_accessor和爲每個角色創建一個虛擬屬性來解決它。然後我根據角色(聯合國)設置複選框。一旦保存,我會檢查哪些值已更改,並相應地添加/刪除角色。這似乎有點矯枉過正,但它有效。如果有人有更好的解決方案,讓我知道!謝謝。 – 2014-09-02 22:16:52

回答

2

因爲我有問題,沒有一次我想出了一個辦法 - 在這裏是解決方案:

更多細節here

每用戶

許多角色,我在這個答案,你有符號的形式角色(下面我修改的方式,它與符號這個解決方案)假設 - 因此與Pundit的情況下工作你正在使用它。

# in models/user.rb 
ROLES = [:admin, :manager, :general, :custom_role, :another_custome_role, :banned] 

可以將多個角色分配給用戶,並使用位掩碼將其存儲到單個整數列中。首先將roles_mask整數列添加到用戶表中。

軌產生遷移add_roles_mask_to_users roles_mask:整數 耙分貝:遷移 接下來,您需要將下面的代碼添加到用戶模型用於獲取和設置用戶所屬角色的列表。這將執行必要的按位操作以將角色數組轉換爲整數字段。

# in models/user.rb 
def roles=(roles) 
    self.roles_mask = (roles & ROLES).map { |r| 2**ROLES.index(r) }.inject(0, :+) 
end 

def roles 
    ROLES.reject do |r| 
    ((roles_mask.to_i || 0) & 2**ROLES.index(r)).zero? 
    end 
end 

這裏一個細小的改動,使其與Rolify &權威人士工作

def roles=(roles) 
    self.roles_mask = (roles.map { |x| x.to_sym } & ROLES).map { |r| 2**ROLES.index(r) }.inject(0, :+) 
    end 

如果你使用的設計沒有強有力的參數,不要忘記attr_accessible補充:角色對你的用戶模型。

如果您使用的是與strong_parameters設計,無論是作爲在Rails 3應用程序寶石,或者是內置在Rails中4,不要忘記給角色添加到允許列表中的控制器

class ApplicationController < ActionController::Base 
    before_filter :configure_permitted_parameters, if: :devise_controller? 

    protected 

    def configure_permitted_parameters 
    devise_parameter_sanitizer.for(:sign_up) {|u| u.permit(:email, :password, :password_confirmation, roles: [])} 
    end 
end 

請參閱Devise文檔中關於強參數的部分。

您可以使用視圖中的複選框來設置這些角色。

<% for role in User::ROLES %> 
    <%= check_box_tag "user[roles][#{role}]", role, @user.roles.include?(role), {:name => "user[roles][]"}%> 
    <%= label_tag "user_roles_#{role}", role.humanize %><br /> 
<% end %> 
<%= hidden_field_tag "user[roles][]", "" %> 

最後,您可以添加一個方便的方式來檢查用戶在Ability類中的角色。

# in models/user.rb 
def is?(role) 
    roles.include?(role.to_s) 
end 

# in models/ability.rb 
can :manage, :all if user.is? :admin 

請參閱自定義操作以限制哪些用戶可以將角色分配給其他用戶。

此功能也被提取到一個叫做role_model的小寶石(代碼& howto)。

如果您不喜歡此位掩碼解決方案,請參閱分離角色模型以獲取其他處理方法。

相關問題