2011-06-05 44 views
6

我正在構建一個Rails 3系統,我需要根據用戶在網站上註冊的路徑爲用戶提供特定角色。我正在使用Devise和康康。Rails根據註冊路徑設計添加角色

因此,例如,路徑

new-fundraiser(或/users/new/fundraiser

需要設置用戶創建user.fundraiser = true,並

new-charity-user(或/users/new/charity

需要設置user.charity_owner = true上用戶創建。

使用Devise和Cancan來完成此操作的最簡單/最佳實踐方法是什麼?

+0

你是否考慮兩種模式的替代? Fundraise和CharityOwner(以及兩條路線,每個模型),而不是DRYest解決方案。 – 2011-06-05 12:45:00

+1

爲什麼不使用單一註冊,用一個選擇框來選擇他們想要註冊的「角色」。甚至可能將角色留在註冊過程之外,讓用戶在第一次登錄時立即設置角色。註冊過程應該非常簡單 – 2011-06-05 13:32:38

+0

不幸的是,這不是一種選擇,因爲我們有兩種不同類型的用戶被對待完全不同,和複選框的解決方案沒有足夠的拋光 – Houen 2011-06-05 15:44:24

回答

6

我會成立一個類似的路線:

match "https://stackoverflow.com/users/new/:role", :to => 'users#new' 

在您的用戶模型我想補充一個訪問:

class User < ActiveRecord::Base 
    def role=(role_name) 
    @role = role_name 
    case role_name 
    when 'charity' 
     self.charity_owner = true 
    when 'fundraiser' 
     self.fundraiser = true 
    else 
     # raise some exception 
    end 
    end 

    def role 
    @role 
    end 
end 

然後在你的用戶#new.html.erb形式添加隱藏字段:

<%= form.hidden_field :role, :value => params[:role] %> 

然後你根本不需要改變你的控制器代碼。

10

非常感謝@ andrew-nesbitt。原來的問題表明@Houen已經在某種程度上定製了Devise。這裏有一個稍微調整的答案,可以與開箱即用的設計和多對多的用戶角色CanCan設置一起使用。

首先,在你的路線,添加:

devise_scope :user do 
    match "https://stackoverflow.com/users/sign_up/:initial_role" => 'devise/registrations#new', :as => 'new_user_with_role' 
end 

然後,您可以參考這樣的路線:

<%= link_to 'here', new_user_with_role_path(:initial_role => 'human') %> 

然後,在你的用戶模型添加

attr_accessible :initial_role 

def initial_role=(role_name) 
    @initial_role = role_name 
    role = Role.find_by_name(role_name) 
    self.roles << role 
end 

def initial_role 
    @initial_role 
end 

而且最後在views/devise/registrations/new.html.erb中添加

<%= f.hidden_field :initial_role, :value => params[:initial_role] %> 
+0

嗨Cailinanne - 我真的很喜歡我們的答案!非常乾淨 - 你會如何調整這個最好的方式來處理在Devise一側添加的角色user.admin?,user.editor ?,就像Devise wike的選項2一樣:https://github.com/plataformatec/devise/wiki /操作方法:-Add-an-Admin-Role – Houen 2011-06-14 13:46:06

+1

@Houen我會推薦使用Rolify來做到這一點 – 2013-10-31 04:47:53

+0

@ AZ.Completely agree。這個舊的問題已經有了新的和改進的工具。對於任何人現在來到這裏,AZ正在談論https://github.com/EppO/rolify – Houen 2013-11-01 11:00:01

1

使用開箱即用的Devise和CanCan,我根據Rails Casts#189「Embedded Association」設置了我的用戶「角色」。然而,我不能讓@ cailinanne的答案與我的設置一起工作,因爲我們假設了不同的角色方法。如果任何人有類似的問題,這是一個從@ cailinanne的答案中借鑑的不太優雅/可靠的方法。它具有不需要修改用戶模型的一個優點。

使用@cailinanne提供的「devise_scope」路由和「link_to」代碼。跳過對用戶模型的更改。最後,使用下面的代碼中的意見/設計/註冊/ new.html.erb:

<% if params[:initial_role] == "admin" %> 
    <%= hidden_field_tag "user[roles][]", :admin %> 
    <% elsif params[:initial_role] == "moderator" %> 
    <%= hidden_field_tag "user[roles][]", :moderator %> 
    <% elsif params[:initial_role] == "author" %> 
    <%= hidden_field_tag "user[roles][]", :author %> 
    <% end %> 

此代碼替換代碼鑄了Rails提供的check_box_tag代碼。

這絕對需要更多的工作。我將在某些時候將if-elsif-elsif邏輯移到控制器中,並將其引用到User.ROLES中,以便在添加/刪除角色時不會中斷。但是,如果您使用Rails Casts「角色」方法,這將幫助您獲得初始角色分配工作。