Rakenduse arendamine ei tähenda ainult uute funktsioonide rakendamist või parandamist. Mõnikord tuleb muudatused tagasi pöörata ja minna tagasi projekti eelmise etapi juurde. Üks sagedane probleem, mis võib tekkida mitme haru kallal töötades, on seotud andmebaasi struktuuri sobiva versiooni säilitamisega. Programmeerijatel, kes kasutavad rööpaid, on nende käsutuses valmislahendused. Need lahendused toetavad andmebaasi muudatuste rakendamist ja kontrollimist - need on migratsioonid. Ma ei hakka kirjeldama, kuidas see toimib ja milliseid võimalusi see pakub - keskendun probleemile, mis seisneb andmebaasi struktuuri sobiva versiooni säilitamises harude vahetamise ajal.
Rakenduse andmebaasikiht on eraldi olend ja seda kontrollivad ainult migratsioonid. Uute migratsioonide loomisel ärge unustage, et andmebaasi struktuuri kavandatud ümberkujundamine oleks pöörduv. Muidugi võime äärmuslikel juhtudel tõsta IrreversibleMigration
aastal alla meetod. See teavitab meid ka sellest, et migratsiooni ei saa tagasi pöörata. Migratsioonil on erinevaid muudatusi, mida me teeme - tabelite, veergude või indeksite loomine, muutmine ja eemaldamine. Kõige tundlikumad on muudatuste suhtes kustutamise ja muutmise toimingud. Miks? Vaatleme järgmist stsenaariumi: Töötame master-haruga, mis on meie peamine töövõrk. Praegu on meil üks tabel:
class CreateArticles < ActiveRecord::Migration
def change
create_table :articles do |t|
t.string :name
t.text :description
t.string :status, null: false
t.timestamps null: false
end
end
end
Meie Artikkel
mudelil on sellised valideerimised, mis nõuavad olemasolu nimi, kirjeldus ja staatus atribuudid.
class Article < ActiveRecord::Base
valideerib :name, presence: true
validates :description, presence: true
validates :status, presence: true
end
Me rakendame muudatusi meie artiklid tabelis funktsioon arendusharu ja me kustutame staatus veerus.
class RemoveStatusColumnFromArticles < ActiveRecord::Migration
def change
remove_column :articles, :status, :string
end
end
Me teostame migratsiooni:
$ [example/feature]: bundle exec rake db:migrate
== 20150605120955 RemoveStatusColumnFromArticles: migrating ===================
-- remove_column(:articles, :status, :string)
-> 0.0717s
== 20150605120955 RemoveStatusColumnFromArticles: migreeritud (0.0718s) ==========
Andmebaasi skeem muutub:
diff --git a/db/schema.rb b/db/schema.rb
index 2a100a9..76438c1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,14 +11,13 @@ #
On tungivalt soovitatav, et te kontrolliksite selle faili oma versioonihaldussüsteemi.
-ActiveRecord::Schema.define(version: 20150605120350) do
+ActiveRecord::Schema.define(version: 20150605120955) do
createtable "articles", force: :cascade do |t|
t.string "nimi"
t.text "description"
- t.string "status", null: false t.datetime "createdat", null: false
t.datetime "updated_at", null: false
end
end
Järgmisena kinnitame muudatused funktsioon haru. Selle probleemi simuleerimiseks lülitame praeguse haru masterile. Alusstruktuuri muudeti migratsiooniga, mis kustutab välja staatus veergu funktsioon haru. Proovime kasutada järgmist käsku:
Article.create!(name: "Kaboom", description: "Lorem ipsum...", status: "active")
Mis juhtub pärast eespool nimetatud toimingute täitmist kood? Viga: ActiveRecord::UnknownAttributeError: Artikli jaoks tundmatu atribuut "status".
tõuseb ja seda andmebaasi ühildumatu struktuuri versiooni tõttu. Enne haru muutmist masteriks peaksime tagasi veeretama migratsiooni, mis kustutab staatus veerg alates Artikkel tabel.
Mida me saame teha, et kontrollida, kas me peame enne harude vahetamist mõned migratsioonid tagasi võtma? Kasutades versioonihaldussüsteemi (siin on see git) saame oma tööd kontrollida, luues kasuliku aliase:
~/.gitconfig
[alias]
migrations = "!f() { git diff --name-only $1..$2 db/migrate | tr -d '[A-Za-z/_.]'; }; f"
Täitmine git migratsiooni põhifunktsioon
käsu tulemuseks on migratsiooniversioonide nimekiri, mis asub aadressil funktsioon filiaalid ja mida ei saa leida kapten.
$ [example/feature]: git migrations master feature
20150605120955
Tänu sellele teabele saame hõlpsasti tagasi võtta andmebaasi struktuuris tehtud muudatused, mis on tehtud enne master'ile üleminekut.
$ [näide/funktsioon]: bundle exec rake db:migrate:down VERSION=20150605120955
== 20150605120955 RemoveStatusColumnFromArticles: reverting ===================
-- add_column(:articles, :status, :string)
-> 0.0009s
== 20150605120955 RemoveStatusColumnFromArticles: reverted (0.0045s) ==========
Veel üks asi, mida me peaksime tegema pärast migratsiooni tagasipööramist, on taastada andmebaasi skeemi staatus.
$ [näide/funktsioon]: git status
Filiaali funktsioonil
Muudatused ei ole kommiteerimiseks valmis:
(kasutage "git add ...", et uuendada seda, mis läheb üle)
(kasutage "git checkout -- ...", et visata muudatused töökataloogis ära)
Muudetud: db/schema.rb
commit'ile ei ole muudatusi lisatud (kasutage "git add" ja/või "git commit -a")
$ [näide/funktsioon]: git checkout db/schema.rb
$ [näide/funktsioon]: git status
Filiaali funktsioonil
ei ole midagi kommiteerida, töökataloog on puhas
Nüüd saame hõlpsasti üle minna kapten haru.
Antud näide ei ole keeruline probleem, kuid see peaks aitama teil mõista, kui oluline on säilitada andmebaasi struktuuri töökonteksti muutumise ajal.