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

Доля значений декларации перечисления с несколькими атрибутами

Я хочу иметь класс с несколькими атрибутами, который сохраняет дни недели с числовыми значениями.

summary_weekday    :integer
collection_weekday :integer

Я думал, что могу сопоставить целые числа со значениями с использованием Enum с двумя объявлениями:

enum summary_weekday: %w(monday tuesday wednesday thursday friday saturday sunday)
enum collection_weekday: %w(monday tuesday wednesday thursday friday saturday sunday)

Но Rails не принимает этого, я не могу определить одно и то же значение дважды в одном классе.

Вы пытались определить перечисление с именем "summary_weekday" на модели "QuestionCategory", но это приведет к созданию метода экземпляра "понедельник?", который уже определен другим перечислением.

Как я могу это решить?

4b9b3361

Ответ 1

По Rails 5.0 вы можете использовать опции _prefix или _suffix, когда вам нужно определить несколько перечислений с одинаковыми значениями. Если переданное значение истинно, методы имеют префикс/суффикс с именем перечисления.

class Invoice < ActiveRecord::Base
  enum verification: [:done, :fail], _prefix: true
end

Также возможно предоставить пользовательский префикс.

class Invoice < ActiveRecord::Base
  enum verification: [:done, :fail], _prefix: :verification_status
end

Ответ 2

То, что вы ищете, не может быть получено enum, поскольку оно попытается создать такие методы, как object.tuesday? для обоих перечислений, что логически неправильно.

Я помню DataMapper ORM, чтобы иметь именно такую ​​поддержку. Для ActiveRecord вам, вероятно, придется вручную создавать методы getter и setter для этих свойств и отображать их там, например:

WEEKDAYS = %w(monday tuesday wednesday thursday friday saturday sunday)

def summary_weekday
  WEEKDAYS[read_attribute(:summary_weekday).to_i] 
end

def summary_weekday=(value)
  write_attribute(:summary_weekday, WEEKDAYS.index(value.to_s))
end

В приведенном выше коде может потребоваться некоторое манипулирование при приведении типов и т.д. Я знаю, что это не общее доказательство, и я действительно буду любить знать лучшее решение этой интересной проблемы; безусловно, будет очень полезно.

Предоставлено - Ruby Forum

Надеюсь, что это поможет.

Ответ 3

Если люди все еще ищут решение для Rails 4, я просто попробовал это на днях, и, похоже, он работает хорошо. Мне нужна подобная система для работы из-за различных проверок, которые администратор должен делать на объекте. Я решил это, создав модельную проблему и используя метод класса в модели:

В моделях /concern/review _states.rb

require 'active_support/concern'

module ReviewStates extend ActiveSupport::Concern

  class_methods do
    REVIEW_STATES = {not_initiated:0, in_progress:1, completed:2}
    SIGNUP_STATES = {pending:0, activated:1, disabled:2}
    def prefix_review_states(prefix)
      Hash[REVIEW_STATES.map { |k,v| [k.to_s.prepend(prefix).to_sym, v] }]
    end
  end
end

В вашей модели:

class ModelName < ActiveRecord::Base
  include ReviewStates

  enum one_status: prefix_review_states("one_")
  enum two_status: prefix_review_states("two_")

Кажется, что все правильные запросы к базе данных.

Удачи!