2009-05-26 62 views
26

我剛剛在rails上學習ruby,我有一個用戶角色表(Owner,Admin和User)。代碼中會有一些地方需要檢查用戶的角色並顯示不同的選項。有沒有人知道如何做到這一點,而不訴諸魔術數字或其他醜陋的方法?列舉類型或替代方法

在ASP.Net Web應用程序,我對我的工作已經看到了這一點,通過使用枚舉類型的實現:

public enum UserRole { Owner = 1, Admin = 2, User = 3 } 

// ... 

if (user.Role == UserRole.Admin) 
    // Show special admin options 

數據庫中的每個不同的作用體現爲枚舉類型的值設置爲數據庫中該角色的ID。這似乎不是一個很好的解決方案,因爲它取決於可能會改變的數據庫知識。即使它是處理這種事情的正確方法,我也不知道如何在rails中使用枚舉類型。

我將不勝感激這件事。

回答

26

紅寶石本身不具有枚舉類型,但此網站展示的方法http://www.rubyfleebie.com/enumerations-and-ruby/

你可以做這樣的事情在您的用戶模式:

#constants 
OWNER = 1 
ADMIN = 2 
USER = 3 

def is_owner? 
    self.role == OWNER 
end 

def is_admin? 
    self.role == ADMIN 
end 

def is_user? 
    self.role == USER 
end 
2

我更喜歡使用適當命名的Authorization這樣的情況插件。

這將讓你

permit "role" 

限制進入角色,並

permit? "role" 

簡單的測試訪問。這兩個代表User#has_role?(role)

不覺得你必須使用他們的ObjectRoles實現。您可以使用Hardwired角色,然後實施自己的User#has_role?(role)方法以使用現有架構。

+0

此外,瑞恩·貝茨有一個名爲康康舞良好的授權寶石和他的網站一個很好的教程(http://railscasts.com/episodes/192 -authorization與 - 康康舞) – 2013-04-09 00:40:32

0

RubyForge上有一個enum plugin所以你做的:

t.column :severity, :enum, :limit => [:low, :medium, :high, :critical] 

這是非常醜陋的使用:limit屬性來傳遞參數,但它是一個更加規範的方式。

要安裝只是做:

script/plugin install svn://rubyforge.org/var/svn/enum-column/plugins/enum-column 

它currenctly使用Rails 2.2.2或更高版本的作品。 Rubyforge鏈接:www.rubyforge.org/projects/enum-column/

4

這似乎是一個非常好的情況下使用我的classy_enum寶石。它基本上允許您定義一組固定的選項,其中每個選項都是具有特定行爲和屬性的類。它有助於減少趨於分散在整個應用程序中的所有條件邏輯。

例如,如果你正在做的事情是這樣的:

class User < ActiveRecord::Base 
    def options 
    if user.is_admin? 
     [...admin options...] 
    else 
     [...non admin options...] 
    end 
    end 
end 

然後與調用:user.options別的地方...

classy_enum允許你這種邏輯移動到一個單獨的地方,有沒有條件邏輯相同的功能:

class User < ActiveRecord::Base 
    classy_enum_attr :role 

    delegate :options, :to => :role 
end 

README有一個工作示例,並詳細介紹了寶石。

2

剛開始學習Rails(來自C#),並有這個完全相同的問題。看來Rails並沒有真正的枚舉,因爲哲學是不同的。我會使用大量的枚舉來嘗試組織C#項目中的所有細節,但也許因爲Rails爲你處理這些東西並不重要。這不是一個真正的答案,只是一個觀察。

12

是否可以在Rails 4.1中添加功能,是您正在尋找的?從博客文章

http://coherence.io/blog/2013/12/17/whats-new-in-rails-4-1.html

複製:

class Bug < ActiveRecord::Base 
    # Relevant schema change looks like this: 
    # 
    # create_table :bugs do |t| 
    # t.column :status, :integer, default: 0 # defaults to the first value (i.e. :unverified) 
    # end 

    enum status: [ :unverified, :confirmed, :assigned, :in_progress, :resolved, :rejected, :reopened ] 

... 

Bug.resolved   # => a scope to find all resolved bugs 
bug.resolved?   # => check if bug has the status resolved 
bug.resolved!   # => update! the bug with status set to resolved 
bug.status    # => a string describing the bug's status 
bug.status = :resolved # => set the bug's status to resolved