2015-10-04 9 views
6

Jak utworzyć migrację w ruby, gdzie domyślnie jest ciąg, a nie Integer, chcę zapisać wyliczenie do bazy danych, ale nie chcę przechowywać go jako Integer, ponieważ wtedy nie ma sensu inna aplikacja, która chce użyć tej samej tabeli. Jak zrobić default: "female" zamiast default:0Jak zapisać wyliczenie jako ciąg do bazy danych w szynach?

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

+0

Co baza danych używasz? –

+0

Używam programu sqlite do programowania i mysql do produkcji –

Odpowiedz

0

Do mojej wiedzy nie jest możliwe ze standardowym Rails wyliczenia. Spójrz na https://github.com/lwe/simple_enum, jest bardziej funkcjonalnie bogaty, a także pozwala na przechowywanie wartości wyliczeniowych jako ciągi do DB (ciąg znaków kolumny, tj. Varchar pod względem DB).

9

enum w Railsach i ENUM type w MySQL to 2 różne rzeczy.

  1. enum w Rails jest tylko nakładką na kolumnie integer więc łatwiej można było korzystać w ciągi zapytań, zamiast liczb całkowitych. Ale na poziomie bazy danych wszystkie są konwertowane na liczby całkowite (automatycznie przez Railsy), ponieważ jest to typ kolumny.

  2. ENUM typu MySQL jest typu dostawcy sprzętu kolumny (na przykład, SQLite doesn't support it, ale PostgreSQL does). W mysql

wyliczenia jest obiektem łańcuch o wartości wybranej z listy dopuszczalnych wartości, które są wyraźnie wyliczone w tym opisie kolumny podczas tworzenia tabeli.

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 | 
+---------+--------+ 

dla migracji, trzeba to zrobić:

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

Jeśli przejdziesz tę trasę, musisz przełączyć się na zrzuty schematu SQL, w przeciwnym razie Railsy wstawią typ kolumny w pliku schema.rb. Przełącz w następujący sposób w config/application.rb: 'config.active_record.schema_format =: sql' –

11

Czytając dokumentację enum można zobaczyć Rails użyć indeksu wartość Array tłumaczyć jako:

Należy pamiętać, że gdy używana jest tablica, niejawne mapowanie z wartości do liczb całkowitych z bazy danych pochodzi z kolejności, w jakiej wartości pojawiają się w tablicy.

Ale jest również powiedziane, że można użyć Hash:

jest to również możliwe, aby wyraźnie map relację między atrybut i całkowitej bazy z Hash.

Z przykład:

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

Więc testowano przy użyciu Rails 4.2.4 i sqlite3 i stworzył klasę User z string typu dla seksu typu oraz Hash w enum z string wartości (używam fem i mal wartości różnią się od żeńskiej i samca):

Migracja:

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 

A w konsoli:

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" 
+2

tak w db jest przechowywane' fem'? –

0

Mam następujące Przechowalnia stanach smyczkowych i skorzystać z korzystnych Szyny Metody pomocnicze:

def self.up 
    add_column :works, :status, :string, null: false, default: 'offering' 
end 

class Work < ApplicationRecord 
    ALL_STATES = %w[canceled offering running payment rating done].freeze 
    enum status: ALL_STATES.zip(ALL_STATES).to_h 
end 
Powiązane problemy