问题
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.
回答1:
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:
- Update your
config/application.rbto containconfig.active_record.schema_format = :sql. - Do a
rake db:structure:dumpto get an initialdb/structure.sql. - Delete
db/schema.rbfrom your directory tree and revision control. - Add
db/structure.sqlto revision control. - Adjust your rake habits:
- Use
db:structure:dumpinstead ofdb:schema:dump - Use
db:structure:loadinstead ofdb:schema:load
- Use
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 enums are a client-side translation between strings and integers but PostgreSQL's enums 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.
来源:https://stackoverflow.com/questions/48508905/enumerated-types-with-activerecord-and-postgresql