Как получить целочисленное значение из перечисления в Rails?

105

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

В enumвыглядит следующим образом :

  enum sale_info: { plan_1: 1, plan_2: 2, plan_3: 3, plan_4: 4, plan_5: 5 }

Как получить целочисленное значение?

я пробовал

Model.sale_info.to_i

Но это возвращает только 0.

Клейтон
источник
Не должно быть Model.sale_info.value.to_i? напримерModel.sale_info.plan_1.to_i
Флориан Гл
Нет ... Потому что я не знаю, в каком плане он хранится в базе данных. Итак, я хочу восстановить его и представить какinteger
Клейтон

Ответы:

140

Вы можете получить целочисленные значения для перечисления из класса, в котором находится перечисление:

Model.sale_infos # Pluralized version of the enum attribute name

Это возвращает хеш вроде:

{ "plan_1" => 1, "plan_2" => 2 ... }

Затем вы можете использовать значение sale_info из экземпляра Modelкласса для доступа к целочисленному значению для этого экземпляра :

my_model = Model.find(123)
Model.sale_infos[my_model.sale_info] # Returns the integer value
Shadwell
источник
139

Вы можете получить целое число так:

my_model = Model.find(123)
my_model[:sale_info] # Returns the integer value

Обновление для рельсов 5

Для рельсов 5 указанный выше метод теперь возвращает строковое значение :(

На данный момент я вижу лучший метод:

my_model.sale_info_before_type_cast

Ответ Шедвелла также продолжает работать для рельсов 5.

Тонкое дерево
источник
1
Это связано с тем, что enum создаст метод sale_info для вашей модели, используйте [: sale_info] для получения значения свойства вместо возврата из метода sale_info.
etlds 05
6
Обратите внимание, что этот метод не работает, если модель не была сохранена. Значение sale_info_before_type_cast (и my_model [: sale_info]) по-прежнему является строкой, если my_model.sale_info была присвоена строка без последующего сохранения.
Тим Смит
42

Рельсы <5

Другой способ - использовать read_attribute():

model = Model.find(123)
model.read_attribute('sale_info')

Рельсы> = 5

Ты можешь использовать read_attribute_before_type_cast

model.read_attribute_before_type_cast(:sale_info)
=> 1
АрашМ
источник
1
@GrantBirchmeier Обновил ответ. Вы можете использовать read_attribute_before_type_cast.
ArashM
До Rails 5 model.read_attribute ('sale_info') равнялся модели [: sale_info]
zw963
1

Мой короткий ответ Model.sale_infos[:plan_2]на тот случай, если вы хотите получить ценностьplan_2

Бриллиант-Дюк
источник
1

Я написал метод в моей модели, чтобы добиться того же в моем приложении Rails 5.1.

Для вашего случая добавьте это в свою модель и при необходимости вызовите его на объекте.

def numeric_sale_info
  self.class.sale_infos[sale_info]
end
shrmn
источник