How to save an enumeration as a row in a database in rails

How to create a migration to ruby, where the default value is a string, not an integer, I want to save the enumeration in the database, but I do not want to store it as Integer, because then there is no point in another application that wants to use the same table . How do I make 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

+11
enums ruby ruby-on-rails
source share
5 answers

As you read the enum documentation, you can see that Rails uses an index of Array values, which is explained as:

Note that when using an array, implicit matching of values ​​with integers of the database comes from the order in which the values ​​are displayed in the array.

But it also says that you can use Hash :

You can also explicitly match the relationship between the attribute and the integer number of the database with the hash.

In the example:

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

So, I tested Rails 4.2.4 and sqlite3 and created a User class with type string for the type of gender and Hash in enum with string values ​​(I use fem and small values ​​are different from women and men):

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 the 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" 
+23
source share

enum in Rails and enum type in MySQL have two different things.

  • enum in Rails is just a wrapper around an integer column, so it’s easier for you to use strings in queries rather than integers. But at the database level, everything is converted to integers (automatically Rails), since this is a column type.

  • enum type in MySQL is a provider-specific column type (for example, SQLite does not support it , but PostgreSQL does ). In MySQL:

ENUM is a string object with a value selected from a list of valid values ​​that are explicitly listed in the column specification at the time the table was created.

 CREATE TABLE shirts ( name VARCHAR(40), size ENUM('x-small', 'small', 'medium', 'large', 'x-large') ); INSERT INTO shirts (name, size) VALUES ('dress shirt','large'), ('t-shirt','medium'), ('polo shirt','small'); SELECT name, size FROM shirts WHERE size = 'medium'; +---------+--------+ | name | size | +---------+--------+ | t-shirt | medium | +---------+--------+ 

For migration you need to do the following:

 class AddSexToUsers < ActiveRecord::Migration def change add_column :users, :sex, "ENUM('female', 'male') DEFAULT 'female'" end end 
+14
source share

I usually do the following:

 # in the migration in db/migrate/… def self.up add_column :works, :status, :string, null: false, default: 'offering' end # in app/models/work.rb class Work < ApplicationRecord ALL_STATES = %w[canceled offering running payment rating done].freeze enum status: ALL_STATES.zip(ALL_STATES).to_h end 

Using a hash as an argument to enum ( see docs ), this line stores the rows in the database. At the same time, this allows you to use all the cool Rails helper methods:

 w = Work.new #=> #<Work id: nil, status: "offering"> w.rating? #=> false w.offering? #=> true w.status #=> "offering" w[:status] #=> "offering" w.done! # INSERT transaction... w.status #=> "done" w[:status] #=> "done" 
+9
source share

Take a look at this Gist, Rails does not provide it out of the box, so you should use worry:

https://gist.github.com/mani47/86096220ccd06fe46f0c09306e9d382d

+1
source share

As far as I know, this is not possible in the standard Rails enumeration. Take a look at https://github.com/lwe/simple_enum , it is more functionally rich, and also allows you to store enum values ​​as strings in DB (a column type string, i.e. varchar in DB terms).

0
source share

All Articles