Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to store enum as string to database in rails

How do I create a migration in ruby where the default is a string rather than an Integer, I want to store enum into the database, but I do not want to store it as Integer, because then it does not make sense to another application that wants to use the same table. How do I do default: "female" instead of default:0

class AddSexToUsers < ActiveRecord::Migration   def change     add_column :users, :sex, :integer, default: 0   end end class User < ActiveRecord::Base   enum sex: [:female, :male]   has_secure_password end 

I

like image 785
James Okpe George Avatar asked Oct 04 '15 21:10

James Okpe George


People also ask

How is enum stored in database?

By default, when an enum is a part of an entity, JPA maps its values into numbers using the ordinal() method. What it means is that without customizations JPA stores enum value as numbers. These numbers are associated with the order in which you define values in the enum.

Can enums be strings?

No they cannot. They are limited to numeric values of the underlying enum type. +1 Good one with the helper method! ToString("F") is useful for formatting to the name of the enum value, if they don't want custom strings.

How does enum work in Rails?

An enum is an attribute where the values map to integers in the database and can be queried by name. Enums also give us the ability to change the state of the data very quickly. This makes it easy to use enums in Rails and saves a lot of time by providing dynamic methods.

Should you store enums in database?

By keeping the enum in your database, and adding a foreign key on the table that contains an enum value you ensure that no code ever enters incorrect values for that column. This helps your data integrity and is the most obvious reason IMO you should have tables for enums.


1 Answers

Reading the enum documentation, you can see Rails use the value index of the Array explained as:

Note that when an Array is used, the implicit mapping from the values to database integers is derived from the order the values appear in the array.

But it is also stated that you can use a Hash:

it's also possible to explicitly map the relation between attribute and database integer with a Hash.

With the example:

class Conversation < ActiveRecord::Base     enum status: { active: 0, archived: 1 }   end 

So I tested using Rails 4.2.4 and sqlite3 and created an User class with a string type for sex type and a Hash in the enum with string values(I am using fem and mal values to differ from female and male):

Migration:

class CreateUsers < ActiveRecord::Migration   def change     create_table :users do |t|       t.string :sex, default: 'fem'     end   end end   

Model:

class User < ActiveRecord::Base   enum sex: { female: 'fem', male: 'mal' } end 

And in console:

u = User.new #=>  #<User id: nil, sex: "fem"> u.male? #=> false u.female? #=> true u.sex #=> "female" u[:sex] #=> "fem" u.male! # INSERT transaction... u.sex #=> "male" u[:sex] #=> "mal" 
like image 134
Doguita Avatar answered Sep 28 '22 05:09

Doguita