Подтвердить что ты не робот

Рельсы Перечисленные типы или альтернативы

Я просто изучаю ruby ​​на рельсах, и у меня есть таблица ролей пользователей (Owner, Admin и User). В коде будут места, где мне нужно проверить роль пользователя и показать разные параметры. Кто-нибудь знает, как это сделать, не прибегая к магическим числам или другим уродливым методам?

В веб-приложениях ASP.Net, над которыми я работал, я видел это, используя перечисленные типы:

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

// ...

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

Каждая отдельная роль в базе данных отражается как перечислимый тип со значением, установленным для идентификатора этой роли в базе данных. Это не похоже на очень хорошее решение, потому что это зависит от знания базы данных, которая может измениться. Даже если это правильный способ справиться с чем-то подобным, я не знаю, как использовать перечисленные типы в рельсах.

Буду признателен за понимание этого вопроса.

4b9b3361

Ответ 1

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

Ответ 2

Может ли функциональность, добавленная в 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 status
bug.status = :resolved # => set the bug status to resolved

Ответ 3

Это похоже на действительно хороший пример использования 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 имеет рабочий пример и подробно описывает драгоценный камень.

Ответ 4

Я предпочитаю использовать подходящий Authorization плагин для подобных ситуаций.

Это позволит вам

permit "role" 

чтобы ограничить доступ к ролям и

permit? "role"

просто проверить доступ. Оба этих делегата на User#has_role?(role).

Не чувствуйте, что вам нужно использовать их реализацию ObjectRoles. Вы можете использовать роли Hardwired, а затем реализовать собственный метод User#has_role?(role) для использования вашей существующей схемы.

Ответ 5

Просто начал изучать Rails (с С#) и имел этот тот же самый вопрос. Кажется, что у Rails действительно нет перечислений, потому что философия отличается. Я бы использовал тонны перечислений, чтобы попытаться организовать все детали в проекте С#, но, возможно, с тех пор, как Rails справляется так много для вас, они не так важны. Это не ответ, просто наблюдение.

Ответ 6

Там есть enum plugin на rubyforge, чтобы вы это сделали:

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

Это довольно уродливо использовать атрибут :limit для передачи параметров, но это более стандартизованный способ.

Для установки просто выполните:

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

он работает с Rails 2.2.2 или новее. Ссылка Rubyforge: www.rubyforge.org/projects/enum-column/