Reputation: 725
I am following this tutorial from SitePoint to set a model property to an Enum value, which is supported by Rails as of 4.1.
Instead of Gender Enum, I am trying to add a Season Enum.
This is the issue I get in my schema.db
# Could not dump table "semesters" because of following StandardError
# Unknown type 'season' for column 'season'
This is my migration
:
class AddSeasonToSemesters < ActiveRecord::Migration[5.1]
def up
execute <<-SQL
CREATE TYPE season AS ENUM ('fall', 'winter', 'spring', 'summer');
SQL
add_column :semesters, :season, :season, index: true
end
def down
remove_column :semesters, :season
execute <<-SQL
DROP TYPE season;
SQL
end
end
And my model
file:
class Semester < ApplicationRecord
enum season: {
fall: 'fall',
winter: 'winter',
spring: 'spring',
summer: 'summer'
}
end
Any idea what I am doing wrong? Any direction would be appreciated, thank you.
Upvotes: 3
Views: 962
Reputation: 434665
You need to switch from db/schema.rb
to db/structure.sql
.
The underlying problem is that schema.rb
is a representation of the database's structure as ActiveRecord sees it but ActiveRecord doesn't understand a lot of things (such as create type
, CHECK constraints, and other things that show up in execute some_raw_sql
statements in migrations) that PostgreSQL does. You can create type
all you want but schema.rb
will never see it.
If you want to use things that ActiveRecord doesn't understand then you have to use db/structure.sql
to store your database's structure. structure.sql
stores the database's structure as the database understands it, not as ActiveRecord understands it.
Switching is easy:
config/application.rb
to contain config.active_record.schema_format = :sql
.rake db:structure:dump
to get an initial db/structure.sql
.db/schema.rb
from your directory tree and revision control.db/structure.sql
to revision control.db:structure:dump
instead of db:schema:dump
db:structure:load
instead of db:schema:load
That said, I'm not sure how well PostgreSQL's native enum
types will interact with ActiveRecord as I've never done it. AR's enum
s are a client-side translation between strings and integers but PostgreSQL's enum
s are handled inside the database and they don't know about each other. There might be conflicts and you will need to be sure to keep them synchronized with each other.
Upvotes: 5