How get integer value from a enum in Rails?
Solution 1
You can get the integer values for an enum from the class the enum is on:
Model.sale_infos # Pluralized version of the enum attribute name
That returns a hash like:
{ "plan_1" => 1, "plan_2" => 2 ... }
You can then use the sale_info value from an instance of the Model
class to access the integer value for that instance:
my_model = Model.find(123)
Model.sale_infos[my_model.sale_info] # Returns the integer value
Solution 2
You can get the integer like so:
my_model = Model.find(123)
my_model[:sale_info] # Returns the integer value
Update for rails 5
For rails 5 the above method now returns the string value :(
The best method I can see for now is:
my_model.sale_info_before_type_cast
Shadwell's answer also continues to work for rails 5.
Solution 3
Rails < 5
Another way would be to use read_attribute()
:
model = Model.find(123)
model.read_attribute('sale_info')
Rails >= 5
You can use read_attribute_before_type_cast
model.read_attribute_before_type_cast(:sale_info)
=> 1
Solution 4
I wrote a method in my Model to achieve the same in my Rails 5.1 app.
Catering for your case, add this into your Model and call it on the object when needed
def numeric_sale_info
self.class.sale_infos[sale_info]
end
Solution 5
My short answer is Model.sale_infos[:plan_2]
in case if you want to get value of plan_2
Comments
-
Cleyton about 4 years
I have a enum in my Model that corresponds to column in the database.
The
enum
looks like:enum sale_info: { plan_1: 1, plan_2: 2, plan_3: 3, plan_4: 4, plan_5: 5 }
How can I get the integer value?
I've tried
Model.sale_info.to_i
But this only returns 0.
-
etlds about 8 yearsIt is because 'enum' will create a method sale_info for your model, use [:sale_info] to get the property value instead of return from sale_info method.
-
Tim Smith over 7 yearsNote that this method does not work if the model has not been saved. The sale_info_before_type_cast value (and my_model[:sale_info]) is still a string if it my_model.sale_info has been assigned a string without a subsequent save.
-
ArashM about 7 years@GrantBirchmeier Updated the answer. You can use
read_attribute_before_type_cast
. -
zw963 over 6 yearsBefore Rails 5, model.read_attribute('sale_info') equal to model[:sale_info]
-
dazonic almost 3 yearsI like this approach. When using
before_type_cast
, it’ll return a string if you’re on an unsaved record you’ve initialised likePost.new status: :unapproved
, but an integer if it’s persisted.