Rails 枚举类型或替代方案

发布于 2024-07-22 04:46:09 字数 477 浏览 7 评论 0原文

我刚刚学习 ruby​​ on Rails,我有一个用户角色表(所有者、管理员和用户)。 代码中有些地方我需要检查用户的角色并显示不同的选项。 有谁知道如何在不诉诸魔法数字或其他丑陋方法的情况下做到这一点?

在我开发的 ASP.Net Web 应用程序中,我看到这是通过使用枚举类型完成的:

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

// ...

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

数据库中的每个不同角色都反映为枚举类型,其值设置为数据库中该角色的 ID。 这似乎不是一个很好的解决方案,因为它依赖于可能改变的数据库知识。 即使这是处理此类问题的正确方法,我也不知道如何在 Rails 中使用枚举类型。

如果您对此事有任何见解,我将不胜感激。

I'm just learning ruby on rails and I have a table of user roles (Owner, Admin, and User). There are going to be places in the code where I need to check the user's role and show different options. Does anyone know how to do this without resorting to magic numbers or other ugly methods?

In ASP.Net web apps I've worked on I've seen this done through the use of enumerated types:

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

// ...

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

Each different role in the database is reflected as an enumerated type with a value set to the ID of that role in the database. That doesn't seem like a very good solution because it depends on knowledge of database that may change. Even if it is the proper way to handle something like this, I don't know how to use enumerated types in rails.

I would appreciate any insight into this matter.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

时间你老了 2024-07-29 04:46:09

Ruby 本身没有枚举类型,但是这个网站展示了一个方法 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

Ruby itself does not have an enumerated type, but this site shows a method http://www.rubyfleebie.com/enumerations-and-ruby/

You could make something like this in your User model:

#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
默嘫て 2024-07-29 04:46:09

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

Could the functionality added in Rails 4.1, be what you are looking for ?

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

Copy from blog post:

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
千秋岁 2024-07-29 04:46:09

这似乎是使用我的 classy_enum gem 的一个非常好的例子。 它本质上允许您定义一组固定的选项,其中每个选项都是一个具有特定行为和属性的类。 它有助于减少分散在整个应用程序中的所有条件逻辑。

例如,如果您正在做这样的事情:

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 有一个工作示例并详细描述了 gem。

This seems like a really good case for using my classy_enum gem. It essentially allows you to define a fixed set of options, where each one is a class with behavior and properties specific to it. It helps cut down on all the conditional logic that tends to get scattered throughout the application.

For example, If you are doing things like this:

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

Then calling as: user.options somewhere else...

classy_enum allows you to move that logic to a separate place and have the same functionality with no conditional logic:

class User < ActiveRecord::Base
  classy_enum_attr :role

  delegate :options, :to => :role
end

The README has a working example and describes the gem in detail.

時窥 2024-07-29 04:46:09

对于这种情况,我更喜欢使用适当命名的 授权 插件。

这将允许您

permit "role" 

限制对角色的访问,并

permit? "role"

简单地测试访问。 这两个委托都委托给 User#has_role?(role)

不要觉得您必须使用他们的 ObjectRoles 实现。 您可以使用 Hardwired 角色,然后实现您自己的 User#has_role?(role) 方法来使用现有架构。

I prefer to use the aptly named Authorization plugin for situations like this.

This will let you

permit "role" 

to restrict access to roles, and

permit? "role"

to simply test for access. Both of these delegate to User#has_role?(role).

Don't feel like you have to use their ObjectRoles implementation. You can use the Hardwired roles and then implement your own User#has_role?(role) method to use your existing schema.

耶耶耶 2024-07-29 04:46:09

刚刚开始学习 Rails(从 C#),并且有这个完全相同的问题。 Rails 似乎并没有真正的枚举,因为理念不同。 我会使用大量的枚举来尝试组织 C# 项目中的所有细节,但也许由于 Rails 为您处理了很多事情,因此它们并不那么重要。 这并不是一个真正的答案,只是一个观察。

Just starting to learn Rails (from C#), and had this exact same question. It seems that Rails doesn't really have enums because the philosophy is different. I would use tons of enums to try to organize all the details in a C# project, but maybe since Rails handles so much for you they aren't that important. It's not really an answer, just an observation.

孤单情人 2024-07-29 04:46:09

rubyforge 上有一个 enum 插件,所以你可以这样做:

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

使用 :limit< 非常难看/code> 属性来传递参数,但这是一种更标准化的方式。

安装方法如下:

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

它目前适用于 Rails 2.2.2 或更高版本。
Rubyforge 链接:www.rubyforge.org/projects/enum-column/

There's a enum plugin on rubyforge so you do:

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

It's pretty ugly to use :limit attribute to pass parameters, but it's a more standardized way.

To install just do:

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

it currenctly works with Rails 2.2.2 or later.
Rubyforge link: www.rubyforge.org/projects/enum-column/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文