Rubyで移行を作成する方法を教えてください。デフォルトは整数ではなく文字列です。列挙型をデータベースに格納したいのですが、整数として格納したくないので、同じテーブルを使用する別のアプリケーションには意味がありません。default: "female"
ではなく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
私
enum
のドキュメントを読むと、次のように表示されますRails説明するArray
の値インデックスを使用:
配列を使用する場合、値からデータベース整数への暗黙的なマッピングは、配列に値が表示される順序から導出されることに注意してください。
ただし、Hash
を使用できることも明記されています。
属性とデータベース整数の関係をハッシュで明示的にマッピングすることもできます。
例では:
class Conversation < ActiveRecord::Base
enum status: { active: 0, archived: 1 }
end
したがって、私はRails 4.2.4とsqliteを使用してテストし、User
タイプのstring
タイプをsexタイプに、Hash
をenum
に作成して、 string
の値(私はfemおよびmalの値をfemaleおよびmaleとは異なる値に使用しています):
移行:
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :sex, default: 'fem'
end
end
end
モデル:
class User < ActiveRecord::Base
enum sex: { female: 'fem', male: 'mal' }
end
そしてコンソールで:
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"
enum
in Railsおよび ENUM
type MySQLは2つの異なるものです。
enum
in Railsはinteger
列のラッパーにすぎないため、整数ではなくクエリで文字列を使用する方が簡単です。しかし、データベースレベルではすべてが整数に変換されます(Railsによって自動的に)。これは列のタイプだからです。
MySQLのENUM
タイプはベンダー固有の列タイプです(たとえば、SQLite サポートしていない ですが、- PostgreSQLはサポートしています )。 MySQLの場合:
ENUMは、テーブル作成時に列指定で明示的に列挙されている許可された値のリストから選択された値を持つ文字列オブジェクトです。
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 |
+---------+--------+
移行するには、これを行う必要があります。
class AddSexToUsers < ActiveRecord::Migration
def change
add_column :users, :sex, "ENUM('female', 'male') DEFAULT 'female'"
end
end
私は通常、次のことを行います。
# 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
enum
のハッシュを引数として使用することで( docsを参照 )、データベースに文字列を格納します。同時に、これにより、すべてのクールなRailsヘルパーメソッドを使用できます。
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"
この要点を見てください、Railsは箱からそれを提供しないので、懸念事項を使用する必要があります:
https://Gist.github.com/mani47/86096220ccd06fe46f0c09306e9d382d
私の知る限り、標準のRails列挙型では不可能です。 https://github.com/lwe/simple_enum を参照してください)、より機能が豊富で、 enum値を文字列としてDBに格納できます(列型文字列、つまりDBに関してはvarchar)。