db/migrate/
eine
entsprechende Migration-Datei
angelegt. Ich zeige Ihnen das Prinzip an einer Shop-Applikation. Legen wir
die mal an:MacBook:~ xyz$ rails new shop [...] MacBook:~ xyz$ cd shop MacBook:shop xyz$
Product
-Model an:MacBook:shop xyz$ rails generate model product name 'price:decimal{7,2}' weight:integer in_stock:boolean expiration_date:date
invoke active_record
create db/migrate/20120508160146_create_products.rb
create app/models/product.rb
invoke test_unit
create test/unit/product_test.rb
create test/fixtures/products.yml
MacBook:shop xyz$
db/migrate/20120508160146_create_products.rb
angelegt.
Wir schauen wir uns die genauer an:class CreateProducts < ActiveRecord::Migration def change create_table :products do |t| t.string :name t.decimal :price, :precision => 7, :scale => 2 t.integer :weight t.boolean :in_stock t.date :expiration_date t.timestamps end end end
change
erstellt und löscht
bei einem Rollback die Datenbank-Tabelle. Die Migrationsdateien haben im
Dateinamen die aktuelle Uhrzeit eingebettet und werden bei einer Migration
(also dem Aufruf von rake db:migrate) in der
chronologischen Reihenfolge abgearbeitet.MacBook:shop xyz$ rake db:migrate
== CreateProducts: migrating =================================================
-- create_table(:products)
-> 0.0017s
== CreateProducts: migrated (0.0018s) ========================================
MacBook:shop xyz$
MacBook:shop xyz$ rake db:migrate
MacBook:shop xyz$
MacBook:shop xyz$ rm db/development.sqlite3 MacBook:shop xyz$ rake db:migrate == CreateProducts: migrating ================================================= -- create_table(:products) -> 0.0017s == CreateProducts: migrated (0.0018s) ======================================== MacBook:shop xyz$
MacBook:shop xyz$ rails generate migration add_height_to_product height:integer
invoke active_record
create db/migrate/20120508160821_add_height_to_product.rb
MacBook:shop xyz$
db/migrate/20120508160821_add_height_to_product.rb
findet sich wieder eine change-Methode:class AddHeightToProduct < ActiveRecord::Migration def change add_column :products, :height, :integer end end
MacBook:shop xyz$ rake db:migrate
== AddHeightToProduct: migrating =============================================
-- add_column(:products, :height, :integer)
-> 0.0049s
== AddHeightToProduct: migrated (0.0050s) ====================================
MacBook:shop xyz$
updated_at
angefügt:MacBook:shop xyz$ rails console Loading development environment (Rails 3.2.3) 1.9.3p194 :001 > Product => Product(id: integer, name: string, price: decimal, weight: integer, in_stock: boolean, expiration_date: date, created_at: datetime, updated_at: datetime, height: integer) 1.9.3p194 :002 > exit MacBook:shop xyz$
app/models/product.rb
das neue Feld in
attr_accessible
eintragen müssen. Sonst haben Sie
keinen Zugriff auf das height
Attribute.MacBook:shop xyz$ rake db:rollback
== AddHeightToProduct: reverting =============================================
-- remove_column("products", :height)
-> 0.0357s
== AddHeightToProduct: reverted (0.0358s) ====================================
MacBook:shop xyz$
MacBook:shop xyz$ rake db:version
Current version: 20120508160146
MacBook:shop xyz$
db/migrate
wieder:MacBook:shop xyz$ ls db/migrate
20120508160146_create_products.rb
20120508160821_add_height_to_product.rb
MacBook:shop xyz$
MacBook:shop xyz$ rake db:migrate VERSION=0
== CreateProducts: reverting =================================================
-- drop_table("products")
-> 0.0007s
== CreateProducts: reverted (0.0007s) ========================================
MacBook:shop xyz$
Person
vs. people
). Aber in
welcher Datenbank werden die Tabellen überhaupt angelegt? Das wird in der
Konfigurationsdatei config/database.yml
definiert:# SQLite version 3.x # gem install sqlite3 # # Ensure the SQLite 3 gem is defined in your Gemfile # gem 'sqlite3' development: adapter: sqlite3 database: db/development.sqlite3 pool: 5 timeout: 5000 # Warning: The database defined as "test" will be erased and # re-generated from your development database when you run "rake". # Do not set this db to the same as development or production. test: adapter: sqlite3 database: db/test.sqlite3 pool: 5 timeout: 5000 production: adapter: sqlite3 database: db/production.sqlite3 pool: 5 timeout: 5000
http://www.yaml.org/
bzw. http://de.wikipedia.org/wiki/YAML
)
drei verschiedene Datenbanken definiert. Für uns ist erst mal nur die
development
-Datenbank (erster Eintrag) wichtig. Per
default benutzt Rails dort SQLite3. SQLite3 mag
nicht die richtige Wahl für die Analyse der weltweit gesammelten
Wetterdaten sein, aber für die schnelle und unkomplizierte Entwicklung von
Rails-Anwendungen lernt man sie schnell zu schätzen. In der
Produktions-Umgebung kann man später immer noch auf „große“
Datenbanken wie MySQL oder PostgreSQL umsteigen.[26]sqlite3
an:MacBook:shop xyz$ sqlite3 db/development.sqlite3 SQLite version 3.7.7 2011-06-25 16:35:41 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> .tables schema_migrations sqlite> .quit MacBook:shop xyz$
MacBook:shop xyz$ rake db:migrate == CreateProducts: migrating ================================================= -- create_table(:products) -> 0.0273s == CreateProducts: migrated (0.0274s) ======================================== == AddHeightToProduct: migrating ============================================= -- add_column(:products, :height, :integer) -> 0.0009s == AddHeightToProduct: migrated (0.0010s) ==================================== MacBook:shop xyz$ sqlite3 db/development.sqlite3 SQLite version 3.7.7 2011-06-25 16:35:41 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> .tables products schema_migrations sqlite> .schema products CREATE TABLE "products" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "price" decimal(7,2), "weight" integer, "in_stock" boolean, "expiration_date" date, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL, "height" integer); sqlite> .quit MacBook:shop xyz$
schema_migrations
wird zur
Versionierung der Migrationen benutzt. Bei der ersten von Rails
durchgeführten Migration wird diese Tabelle angelegt, falls sie noch nicht
vorhanden ist.http://de.wikipedia.org/wiki/Datenbankindex
eine kurze Einführung. Kurzversion: Damit werden Suchen für eine bestimmte
Tabellen-Spalte schneller.name
in der Tabelle products
indizieren. Dafür erstellen wir eine neue Migration:MacBook:shop xyz$ rails generate migration create_index
invoke active_record
create db/migrate/20120508162243_create_index.rb
MacBook:shop xyz$
db/migrate/20101201224922_create_index.rb
legen wir
mit add_index
in der Methode
self.up
den Index an, und in der Methode
self.down
löschen wir ihn mit
remove_index
wieder:class CreateIndex < ActiveRecord::Migration def up add_index :products, :name end def down remove_index :products, :name end end
MacBook:shop xyz$ rake db:migrate
== CreateIndex: migrating ====================================================
-- add_index(:products, :name)
-> 0.0009s
== CreateIndex: migrated (0.0009s) ===========================================
MacBook:shop xyz$
name
)
sähe der Befehl so aus:MacBook:shop xyz$ rails generate model product name:string:index 'price:decimal{7,2}' weight:integer in_stock:boolean expiration_date:date
invoke active_record
create db/migrate/20120508160146_create_products.rb
create app/models/product.rb
invoke test_unit
create test/unit/product_test.rb
create test/fixtures/products.yml
MacBook:shop xyz$
id:integer
NOT
NULL AUTO_INCREMENT.
created_at:datetime
updated_at:datetime
[26] Einige Entwickler sind der Ansicht, dass man auf jeden Fall immer mit der gleichen Datenbank entwicklen soll, die man später auch in der Produktion und im Testing benutzt. Andere sagen, dass diese bei der Verwendung von ORM-Abstraktions-Layern nicht notwendig sei. Bitte entscheiden Sie hier selber. Ich programmiere eine Rails-Applikation oft mit SQLite und verwende in der Produktion oft MySQL.