web-dev-qa-db-ja.com

enumを文字列としてデータベースにrailsに保存する方法

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

14

enum のドキュメントを読むと、次のように表示されますRails説明するArrayの値インデックスを使用:

配列を使用する場合、値からデータベース整数への暗黙的なマッピングは、配列に値が表示される順序から導出されることに注意してください。

ただし、Hashを使用できることも明記されています。

属性とデータベース整数の関係をハッシュで明示的にマッピングすることもできます。

例では:

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

したがって、私はRails 4.2.4sqliteを使用してテストし、Userタイプのstringタイプをsexタイプに、Hashenumに作成して、 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"
27
Doguita

enum in Railsおよび ENUM type MySQLは2つの異なるものです。

  1. enum in Railsはinteger列のラッパーにすぎないため、整数ではなくクエリで文字列を使用する方が簡単です。しかし、データベースレベルではすべてが整数に変換されます(Railsによって自動的に)。これは列のタイプだからです。

  2. 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
14
Alexey Shein

私は通常、次のことを行います。

# 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"
13
schmijos

この要点を見てください、Railsは箱からそれを提供しないので、懸念事項を使用する必要があります:

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

2
mani_007

私の知る限り、標準のRails列挙型では不可能です。 https://github.com/lwe/simple_enum を参照してください)、より機能が豊富で、 enum値を文字列としてDBに格納できます(列型文字列、つまりDBに関してはvarchar)。

0
The Ancient