Ruby on Rails
ActiveRecord-migraties
Zoeken…
parameters
Kolomtype | Beschrijving |
---|---|
:primary_key | Hoofdsleutel |
:string | Kortere gegevenstype. Staat limit voor maximaal aantal tekens. |
:text | Langere hoeveelheid tekst. Staat limit voor maximaal aantal bytes. |
:integer | Geheel getal. Staat limit voor maximaal aantal bytes. |
:bigint | Groter geheel getal |
:float | Vlotter |
:decimal | Decimaal getal met variabele precisie. Biedt precision en scale . |
:numeric | Biedt precision en scale . |
:datetime | DateTime-object voor datums / tijden. |
:time | Tijd object voor tijden. |
:date | Datumobject voor datums. |
:binary | Binaire data. Staat limit voor maximaal aantal bytes. |
:boolean | Boolean |
Opmerkingen
De meeste migratiebestanden bevinden zich in
db/migrate/
directory. Ze worden geïdentificeerd door een UTC-tijdstempel aan het begin van hun bestandsnaam:YYYYMMDDHHMMSS_create_products.rb
.De opdracht voor het
rails generate
kan worden ingekort totrails g
.Als een
:type
niet wordt doorgegeven aan een veld, wordt standaard een tekenreeks gebruikt.
Voer specifieke migratie uit
Gebruik db:migrate:up
of db:migrate:down
om een specifieke migratie naar boven of naar db:migrate:down
.
Een specifieke migratie:
rake db:migrate:up VERSION=20090408054555
rails db:migrate:up VERSION=20090408054555
Down een specifieke migratie:
rake db:migrate:down VERSION=20090408054555
rails db:migrate:down VERSION=20090408054555
Het versienummer in de bovenstaande opdrachten is het numerieke voorvoegsel in de bestandsnaam van de migratie. Als u bijvoorbeeld wilt migreren naar de migratie 20160515085959_add_name_to_users.rb
, gebruikt u 20160515085959
als het versienummer.
Maak een join-tabel
Voer de opdracht uit om een join-tabel tussen students
en courses
te maken:
$ rails g migration CreateJoinTableStudentCourse student course
Dit genereert de volgende migratie:
class CreateJoinTableStudentCourse < ActiveRecord::Migration[5.0]
def change
create_join_table :students, :courses do |t|
# t.index [:student_id, :course_id]
# t.index [:course_id, :student_id]
end
end
end
Migraties uitvoeren in verschillende omgevingen
Voer deze shell-opdracht uit om migraties in de test
voeren:
rake db:migrate RAILS_ENV=test
Vanaf Rails 5.0 kunt u rails
plaats van rake
:
rails db:migrate RAILS_ENV=test
Voeg een nieuwe kolom toe aan een tabel
Om een nieuwe kolom toe te voegen name
aan de users
tabel, voert u de opdracht:
rails generate migration AddNameToUsers name
Dit genereert de volgende migratie:
class AddNameToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :name, :string
end
end
Wanneer de migratienaam de vorm AddXXXToTABLE_NAME
gevolgd door een lijst met kolommen met gegevenstypen, bevat de gegenereerde migratie de juiste add_column
instructies.
Voeg een nieuwe kolom met een index toe
Voer de opdracht uit om een nieuwe geïndexeerde kolom- email
toe te voegen aan de users
:
rails generate migration AddEmailToUsers email:string:index
Dit genereert de volgende migratie:
class AddEmailToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :email, :string
add_index :users, :email
end
end
Verwijder een bestaande kolom uit een tabel
Om bestaande kolom te verwijderen name
van users
tabel, voert u de opdracht:
rails generate migration RemoveNameFromUsers name:string
Dit genereert de volgende migratie:
class RemoveNameFromUsers < ActiveRecord::Migration[5.0]
def change
remove_column :users, :name, :string
end
end
Als de migratienaam de vorm RemoveXXXFromYYY
gevolgd door een lijst met kolommen met gegevenstypen, bevat de gegenereerde migratie de juiste remove_column
instructies.
Hoewel het niet verplicht is om het gegevenstype (bijvoorbeeld :string
) op te geven als parameter om remove_column
te remove_column
, wordt het ten zeerste aanbevolen. Als het gegevenstype niet is opgegeven, is de migratie niet omkeerbaar.
Voeg een referentiekolom toe aan een tabel
Voer deze opdracht uit om een verwijzing naar een team
aan de users
toe te voegen:
$ rails generate migration AddTeamRefToUsers team:references
Dit genereert de volgende migratie:
class AddTeamRefToUsers < ActiveRecord::Migration[5.0]
def change
add_reference :users, :team, foreign_key: true
end
end
Die migratie maakt een team_id
kolom in de users
.
Als u een geschikte index
en foreign_key
wilt toevoegen aan de toegevoegde kolom, wijzigt u de opdracht in rails generate migration AddTeamRefToUsers team:references:index
te rails generate migration AddTeamRefToUsers team:references:index
. Dit genereert de volgende migratie:
class AddTeamRefToUsers < ActiveRecord::Migration
def change
add_reference :users, :team, index: true
add_foreign_key :users, :teams
end
end
Als je je referentiekolom een andere naam wilt geven dan wat Rails automatisch genereert, voeg je het volgende toe aan je migratie: (bijvoorbeeld: je wilt misschien de User
bellen die de Post
als Author
aangemaakt in de Post
)
class AddAuthorRefToPosts < ActiveRecord::Migration
def change
add_reference :posts, :author, references: :users, index: true
end
end
Maak een nieuwe tabel
Om een nieuwe users
tafel met de kolommen name
en salary
, voert u de opdracht:
rails generate migration CreateUsers name:string salary:decimal
Dit genereert de volgende migratie:
class CreateUsers < ActiveRecord::Migration[5.0]
def change
create_table :users do |t|
t.string :name
t.decimal :salary
end
end
end
Wanneer de migratienaam de vorm CreateXXX
gevolgd door een lijst met kolommen met gegevenstypen, wordt een migratie gegenereerd die de tabel XXX
met de weergegeven kolommen maakt.
Meerdere kolommen aan een tabel toevoegen
Om meerdere kolommen aan een tabel toe te voegen, scheidt u het field:type
paren met spaties bij gebruik van rails generate migration
opdracht rails generate migration
.
De algemene syntaxis is:
rails generate migration NAME [field[:type][:index] field[:type][:index]] [options]
Het volgende zal bijvoorbeeld name
, salary
en email
mailvelden toevoegen aan de users
:
rails generate migration AddDetailsToUsers name:string salary:decimal email:string
Dat genereert de volgende migratie:
class AddDetailsToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :name, :string
add_column :users, :salary, :decimal
add_column :users, :email, :string
end
end
Lopende migraties
Uitvoeren commando:
rake db:migrate
rails db:migrate
Als u de doelversie opgeeft, worden de vereiste migraties uitgevoerd (omhoog, omlaag, wijzigen) totdat de opgegeven versie is bereikt. Hier is het version number
het numerieke voorvoegsel op de bestandsnaam van de migratie.
rake db:migrate VERSION=20080906120000
rails db:migrate VERSION=20080906120000
Terugdraaimigraties
Om rollback
van de nieuwste migratie, hetzij door het terugzetten van de change
methode of door het uitvoeren van de down
-methode. Uitvoeren commando:
rake db:rollback
rails db:rollback
Terugdraaien van de laatste 3 migraties
rake db:rollback STEP=3
rails db:rollback STEP=3
STEP
geeft het aantal migraties om terug te zetten.
Terugdraaien van alle migraties
rake db:rollback VERSION=0
rails db:rollback VERSION=0
Tabellen wijzigen
Als u een tabel met een verkeerd schema hebt gemaakt, is de eenvoudigste manier om de kolommen en hun eigenschappen te wijzigen change_table
. Bekijk het volgende voorbeeld:
change_table :orders do |t|
t.remove :ordered_at # removes column ordered_at
t.string :skew_number # adds a new column
t.index :skew_number #creates an index
t.rename :location, :state #renames location column to state
end
De bovenstaande migratie wijzigt een orders
. Hier is een regel-voor-regel beschrijving van de wijzigingen:
-
t.remove :ordered_at
verwijdert de kolomordered_at
van de tafelorders
. -
t.string :skew_number
voegt een nieuwe string-type kolom met de naamskew_number
in deorders
tabel. -
t.index :skew_number
voegt een index op deskew_number
kolom in deorders
tabel. -
t.rename :location, :state
hernoemt delocation
kolom in deorders
tabelstate
.
Voeg een unieke kolom toe aan een tabel
Voer de volgende opdracht uit om een nieuwe unieke kolom- email
aan users
toe te voegen:
rails generate migration AddEmailToUsers email:string:uniq
Hiermee wordt de volgende migratie gemaakt:
class AddEmailToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :email, :string
add_index :users, :email, unique: true
end
end
Wijzig het type van een bestaande kolom
Voer de volgende opdracht uit om een bestaande kolom in Rails met een migratie te wijzigen:
rails g migration change_column_in_table
Hiermee maakt u een nieuw migratiebestand in de directory db/migration
(als dit nog niet bestaat), dat het bestand bevat met het voorvoegsel Tijdstempel en Naam migratiebestand met de onderstaande inhoud:
def change
change_column(:table_name, :column_name, :new_type)
end
Rails Guide - Kolommen wijzigen
Een langere maar veiligere methode
De bovenstaande code voorkomt dat de gebruiker de migratie ooit terugdraait. U kunt dit probleem voorkomen door de change
op te splitsen in afzonderlijke methoden voor up
en down
:
def up
change_column :my_table, :my_column, :new_type
end
def down
change_column :my_table, :my_column, :old_type
end
Migraties opnieuw uitvoeren
U kunt terugdraaien en vervolgens opnieuw migreren met de opdracht redo
. Dit is eigenlijk een snelkoppeling die rollback
en migrate
combineert.
Uitvoeren commando:
rake db:migrate:redo
rails db:migrate:redo
U kunt de STEP
parameter gebruiken om meer dan één versie terug te gaan.
Om bijvoorbeeld 3 migraties terug te gaan:
rake db:migrate:redo STEP=3
rails db:migrate:redo STEP=3
Kolom toevoegen met standaardwaarde
In het volgende voorbeeld wordt een admin
aan de users
en krijgt die kolom de standaardwaarde false
.
class AddDetailsToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :admin, :boolean, default: false
end
end
Migraties met standaardwaarden kunnen lang duren in grote tabellen met bijvoorbeeld PostgreSQL. Dit komt omdat elke rij moet worden bijgewerkt met de standaardwaarde voor de nieuw toegevoegde kolom. Om dit te omzeilen (en downtime tijdens implementaties te verminderen), kunt u uw migratie in drie stappen splitsen:
- Voeg een
add_column
-migration toe vergelijkbaar met die hierboven, maar stel geen standaardwaarde in - Implementeer en update de kolom in een harktaak of op de console terwijl uw app actief is. Zorg ervoor dat uw toepassing al gegevens naar die kolom schrijft voor nieuwe / bijgewerkte rijen.
- Voeg nog
change_column
migratie vanchange_column
, die vervolgens de standaardwaarde van die kolom wijzigt in de gewenste standaardwaarde
Verbied nulwaarden
Om null
waarden in uw tabelkolommen te verbieden, voegt u de parameter :null
aan uw migratie, als volgt:
class AddPriceToProducts < ActiveRecord::Migration
def change
add_column :products, :float, null: false
end
end
Migratiestatus controleren
We kunnen de status van migraties controleren door te draaien
rake db:migrate:status
rails db:migrate:status
De uitvoer ziet er zo uit:
Status Migration ID Migration Name
--------------------------------------------------
up 20140711185212 Create documentation pages
up 20140724111844 Create nifty attachments table
up 20140724114255 Create documentation screenshots
up 20160213170731 Create owners
up 20160218214551 Create users
up 20160221162159 ********** NO FILE **********
up 20160222231219 ********** NO FILE **********
Onder het statusveld betekent up
dat de migratie is uitgevoerd en down
betekent dat we de migratie moeten uitvoeren.
Maak een hstore-kolom
Hstore
kolommen kunnen handig zijn om instellingen op te slaan. Ze zijn beschikbaar in PostgreSQL-databases nadat u de extensie hebt ingeschakeld.
class CreatePages < ActiveRecord::Migration[5.0]
def change
create_table :pages do |t|
enable_extension 'hstore' unless extension_enabled?('hstore')
t.hstore :settings
t.timestamps
end
end
end
Voeg een zelfreferentie toe
Een zelfverwijzing kan nuttig zijn om een hiërarchische boomstructuur te maken. Dit kan worden bereikt met add_reference
in een migratie.
class AddParentPages < ActiveRecord::Migration[5.0]
def change
add_reference :pages, :pages
end
end
De kolom met de externe sleutel wordt pages_id
. Als u een beslissing wilt nemen over de kolomnaam van de externe sleutel, moet u eerst de kolom maken en daarna de referentie toevoegen.
class AddParentPages < ActiveRecord::Migration[5.0]
def change
add_column :pages, :parent_id, :integer, null: true, index: true
add_foreign_key :pages, :pages, column: :parent_id
end
end
Maak een matrixkolom
Een array
wordt ondersteund door PostgreSQL. Rails converteert een PostgreSQL-array automatisch naar een Ruby-array en vice versa.
Maak een tabel met een array
:
create_table :products do |t|
t.string :name
t.text :colors, array: true, default: []
end
Voeg een array
aan een bestaande tabel:
add_column :products, :colors, array: true, default: []
Voeg een index toe voor een array
:
add_index :products, :colors, using: 'gin'
Een NOT NULL-beperking toevoegen aan bestaande gegevens
Stel dat u een externe sleutel company_id
wilt toevoegen aan de users
en dat u er een NOT NULL
beperking op wilt hebben. Als u al gegevens in users
, moet u dit in meerdere stappen doen.
class AddCompanyIdToUsers < ActiveRecord::Migration
def up
# add the column with NULL allowed
add_column :users, :company_id, :integer
# make sure every row has a value
User.find_each do |user|
# find the appropriate company record for the user
# according to your business logic
company = Company.first
user.update!(company_id: company.id)
end
# add NOT NULL constraint
change_column_null :users, :company_id, false
end
# Migrations that manipulate data must use up/down instead of change
def down
remove_column :users, :company_id
end
end