Como obter valor inteiro de um enum no Rails?

105

Eu tenho um enum em meu modelo que corresponde a coluna no banco de dados.

Os enumparece:

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

Como posso obter o valor inteiro?

eu tentei

Model.sale_info.to_i

Mas isso retorna apenas 0.

Cleyton
fonte
Não deveria ser Model.sale_info.value.to_i? por exemploModel.sale_info.plan_1.to_i
Florian Gl
Não opa ... Porque não sei em qual plano está o banco de dados. Então, eu quero recuperá-lo e lançá-lo como uminteger
Cleyton

Respostas:

140

Você pode obter os valores inteiros para um enum da classe em que o enum está:

Model.sale_infos # Pluralized version of the enum attribute name

Isso retorna um hash como:

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

Você pode então usar o valor sale_info de uma instância da Modelclasse para acessar o valor inteiro dessa instância :

my_model = Model.find(123)
Model.sale_infos[my_model.sale_info] # Returns the integer value
Shadwell
fonte
139

Você pode obter o número inteiro assim:

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

Atualização para trilhos 5

Para trilhos 5, o método acima agora retorna o valor da string :(

O melhor método que posso ver agora é:

my_model.sale_info_before_type_cast

A resposta de Shadwell também continua a funcionar para o Rails 5.

Subtletree
fonte
1
É porque 'enum' criará um método sale_info para o seu modelo, use [: sale_info] para obter o valor da propriedade em vez do retorno do método sale_info.
etlds
6
Observe que este método não funciona se o modelo não foi salvo. O valor sale_info_before_type_cast (e my_model [: sale_info]) ainda é uma string se my_model.sale_info tiver recebido uma string sem um salvamento subsequente.
Tim Smith,
42

Rails <5

Outra forma seria usar read_attribute():

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

Trilhos> = 5

Você pode usar read_attribute_before_type_cast

model.read_attribute_before_type_cast(:sale_info)
=> 1
ArashM
fonte
1
@GrantBirchmeier Atualizou a resposta. Você pode usar read_attribute_before_type_cast.
ArashM
Antes do Rails 5, model.read_attribute ('sale_info') igual ao model [: sale_info]
zw963
1

Minha resposta curta é Model.sale_infos[:plan_2]se você deseja obter o valor deplan_2

Brilliant-DucN
fonte
1

Eu escrevi um método em meu modelo para conseguir o mesmo em meu aplicativo Rails 5.1.

Catering para o seu caso, adicione isso ao seu modelo e chame-o no objeto quando necessário

def numeric_sale_info
  self.class.sale_infos[sale_info]
end
Shrmn
fonte