migrations.textile 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900
  1. h2. Migrations
  2. Migrations are a convenient way for you to alter your database in a structured
  3. and organized manner. You could edit fragments of SQL by hand but you would then
  4. be responsible for telling other developers that they need to go and run them.
  5. You'd also have to keep track of which changes need to be run against the
  6. production machines next time you deploy.
  7. Active Record tracks which migrations have already been run so all you have to
  8. do is update your source and run +rake db:migrate+. Active Record will work out
  9. which migrations should be run. It will also update your +db/schema.rb+ file to
  10. match the structure of your database.
  11. Migrations also allow you to describe these transformations using Ruby. The
  12. great thing about this is that (like most of Active Record's functionality) it
  13. is database independent: you don't need to worry about the precise syntax of
  14. +CREATE TABLE+ any more than you worry about variations on +SELECT *+ (you can
  15. drop down to raw SQL for database specific features). For example you could use
  16. SQLite3 in development, but MySQL in production.
  17. In this guide, you'll learn all about migrations including:
  18. * The generators you can use to create them
  19. * The methods Active Record provides to manipulate your database
  20. * The Rake tasks that manipulate them
  21. * How they relate to +schema.rb+
  22. endprologue.
  23. h3. Anatomy of a Migration
  24. Before we dive into the details of a migration, here are a few examples of the
  25. sorts of things you can do:
  26. <ruby>
  27. class CreateProducts < ActiveRecord::Migration
  28. def up
  29. create_table :products do |t|
  30. t.string :name
  31. t.text :description
  32. t.timestamps
  33. end
  34. end
  35. def down
  36. drop_table :products
  37. end
  38. end
  39. </ruby>
  40. This migration adds a table called +products+ with a string column called +name+
  41. and a text column called +description+. A primary key column called +id+ will
  42. also be added, however since this is the default we do not need to ask for this.
  43. The timestamp columns +created_at+ and +updated_at+ which Active Record
  44. populates automatically will also be added. Reversing this migration is as
  45. simple as dropping the table.
  46. Migrations are not limited to changing the schema. You can also use them to fix
  47. bad data in the database or populate new fields:
  48. <ruby>
  49. class AddReceiveNewsletterToUsers < ActiveRecord::Migration
  50. def up
  51. change_table :users do |t|
  52. t.boolean :receive_newsletter, :default => false
  53. end
  54. User.update_all ["receive_newsletter = ?", true]
  55. end
  56. def down
  57. remove_column :users, :receive_newsletter
  58. end
  59. end
  60. </ruby>
  61. NOTE: Some "caveats":#using-models-in-your-migrations apply to using models in
  62. your migrations.
  63. This migration adds a +receive_newsletter+ column to the +users+ table. We want
  64. it to default to +false+ for new users, but existing users are considered to
  65. have already opted in, so we use the User model to set the flag to +true+ for
  66. existing users.
  67. Rails 3.1 makes migrations smarter by providing a new <tt>change</tt> method.
  68. This method is preferred for writing constructive migrations (adding columns or
  69. tables). The migration knows how to migrate your database and reverse it when
  70. the migration is rolled back without the need to write a separate +down+ method.
  71. <ruby>
  72. class CreateProducts < ActiveRecord::Migration
  73. def change
  74. create_table :products do |t|
  75. t.string :name
  76. t.text :description
  77. t.timestamps
  78. end
  79. end
  80. end
  81. </ruby>
  82. h4. Migrations are Classes
  83. A migration is a subclass of <tt>ActiveRecord::Migration</tt> that implements
  84. two methods: +up+ (perform the required transformations) and +down+ (revert
  85. them).
  86. Active Record provides methods that perform common data definition tasks in a
  87. database independent way (you'll read about them in detail later):
  88. * +add_column+
  89. * +add_index+
  90. * +change_column+
  91. * +change_table+
  92. * +create_table+
  93. * +drop_table+
  94. * +remove_column+
  95. * +remove_index+
  96. * +rename_column+
  97. If you need to perform tasks specific to your database (for example create a
  98. "foreign key":#active-record-and-referential-integrity constraint) then the
  99. +execute+ method allows you to execute arbitrary SQL. A migration is just a
  100. regular Ruby class so you're not limited to these functions. For example after
  101. adding a column you could write code to set the value of that column for
  102. existing records (if necessary using your models).
  103. On databases that support transactions with statements that change the schema
  104. (such as PostgreSQL or SQLite3), migrations are wrapped in a transaction. If the
  105. database does not support this (for example MySQL) then when a migration fails
  106. the parts of it that succeeded will not be rolled back. You will have to rollback
  107. the changes that were made by hand.
  108. h4. What's in a Name
  109. Migrations are stored as files in the +db/migrate+ directory, one for each
  110. migration class. The name of the file is of the form
  111. +YYYYMMDDHHMMSS_create_products.rb+, that is to say a UTC timestamp
  112. identifying the migration followed by an underscore followed by the name
  113. of the migration. The name of the migration class (CamelCased version)
  114. should match the latter part of the file name. For example
  115. +20080906120000_create_products.rb+ should define class +CreateProducts+ and
  116. +20080906120001_add_details_to_products.rb+ should define
  117. +AddDetailsToProducts+. If you do feel the need to change the file name then you
  118. <em>have to</em> update the name of the class inside or Rails will complain
  119. about a missing class.
  120. Internally Rails only uses the migration's number (the timestamp) to identify
  121. them. Prior to Rails 2.1 the migration number started at 1 and was incremented
  122. each time a migration was generated. With multiple developers it was easy for
  123. these to clash requiring you to rollback migrations and renumber them. With
  124. Rails 2.1+ this is largely avoided by using the creation time of the migration
  125. to identify them. You can revert to the old numbering scheme by adding the
  126. following line to +config/application.rb+.
  127. <ruby>
  128. config.active_record.timestamped_migrations = false
  129. </ruby>
  130. The combination of timestamps and recording which migrations have been run
  131. allows Rails to handle common situations that occur with multiple developers.
  132. For example Alice adds migrations +20080906120000+ and +20080906123000+ and Bob
  133. adds +20080906124500+ and runs it. Alice finishes her changes and checks in her
  134. migrations and Bob pulls down the latest changes. When Bob runs +rake db:migrate+,
  135. Rails knows that it has not run Alice's two migrations so it executes the +up+ method for each migration.
  136. Of course this is no substitution for communication within the team. For
  137. example, if Alice's migration removed a table that Bob's migration assumed to
  138. exist, then trouble would certainly strike.
  139. h4. Changing Migrations
  140. Occasionally you will make a mistake when writing a migration. If you have
  141. already run the migration then you cannot just edit the migration and run the
  142. migration again: Rails thinks it has already run the migration and so will do
  143. nothing when you run +rake db:migrate+. You must rollback the migration (for
  144. example with +rake db:rollback+), edit your migration and then run +rake db:migrate+ to run the corrected version.
  145. In general editing existing migrations is not a good idea: you will be creating
  146. extra work for yourself and your co-workers and cause major headaches if the
  147. existing version of the migration has already been run on production machines.
  148. Instead, you should write a new migration that performs the changes you require.
  149. Editing a freshly generated migration that has not yet been committed to source
  150. control (or, more generally, which has not been propagated beyond your
  151. development machine) is relatively harmless.
  152. h4. Supported Types
  153. Active Record supports the following database column types:
  154. * +:binary+
  155. * +:boolean+
  156. * +:date+
  157. * +:datetime+
  158. * +:decimal+
  159. * +:float+
  160. * +:integer+
  161. * +:primary_key+
  162. * +:string+
  163. * +:text+
  164. * +:time+
  165. * +:timestamp+
  166. These will be mapped onto an appropriate underlying database type. For example,
  167. with MySQL the type +:string+ is mapped to +VARCHAR(255)+. You can create
  168. columns of types not supported by Active Record when using the non-sexy syntax,
  169. for example
  170. <ruby>
  171. create_table :products do |t|
  172. t.column :name, 'polygon', :null => false
  173. end
  174. </ruby>
  175. This may however hinder portability to other databases.
  176. h3. Creating a Migration
  177. h4. Creating a Model
  178. The model and scaffold generators will create migrations appropriate for adding
  179. a new model. This migration will already contain instructions for creating the
  180. relevant table. If you tell Rails what columns you want, then statements for
  181. adding these columns will also be created. For example, running
  182. <shell>
  183. $ rails generate model Product name:string description:text
  184. </shell>
  185. will create a migration that looks like this
  186. <ruby>
  187. class CreateProducts < ActiveRecord::Migration
  188. def change
  189. create_table :products do |t|
  190. t.string :name
  191. t.text :description
  192. t.timestamps
  193. end
  194. end
  195. end
  196. </ruby>
  197. You can append as many column name/type pairs as you want. By default, the
  198. generated migration will include +t.timestamps+ (which creates the
  199. +updated_at+ and +created_at+ columns that are automatically populated
  200. by Active Record).
  201. h4. Creating a Standalone Migration
  202. If you are creating migrations for other purposes (for example to add a column
  203. to an existing table) then you can also use the migration generator:
  204. <shell>
  205. $ rails generate migration AddPartNumberToProducts
  206. </shell>
  207. This will create an empty but appropriately named migration:
  208. <ruby>
  209. class AddPartNumberToProducts < ActiveRecord::Migration
  210. def change
  211. end
  212. end
  213. </ruby>
  214. If the migration name is of the form "AddXXXToYYY" or "RemoveXXXFromYYY" and is
  215. followed by a list of column names and types then a migration containing the
  216. appropriate +add_column+ and +remove_column+ statements will be created.
  217. <shell>
  218. $ rails generate migration AddPartNumberToProducts part_number:string
  219. </shell>
  220. will generate
  221. <ruby>
  222. class AddPartNumberToProducts < ActiveRecord::Migration
  223. def change
  224. add_column :products, :part_number, :string
  225. end
  226. end
  227. </ruby>
  228. Similarly,
  229. <shell>
  230. $ rails generate migration RemovePartNumberFromProducts part_number:string
  231. </shell>
  232. generates
  233. <ruby>
  234. class RemovePartNumberFromProducts < ActiveRecord::Migration
  235. def up
  236. remove_column :products, :part_number
  237. end
  238. def down
  239. add_column :products, :part_number, :string
  240. end
  241. end
  242. </ruby>
  243. You are not limited to one magically generated column, for example
  244. <shell>
  245. $ rails generate migration AddDetailsToProducts part_number:string price:decimal
  246. </shell>
  247. generates
  248. <ruby>
  249. class AddDetailsToProducts < ActiveRecord::Migration
  250. def change
  251. add_column :products, :part_number, :string
  252. add_column :products, :price, :decimal
  253. end
  254. end
  255. </ruby>
  256. As always, what has been generated for you is just a starting point. You can add
  257. or remove from it as you see fit by editing the
  258. db/migrate/YYYYMMDDHHMMSS_add_details_to_products.rb file.
  259. NOTE: The generated migration file for destructive migrations will still be
  260. old-style using the +up+ and +down+ methods. This is because Rails needs to know
  261. the original data types defined when you made the original changes.
  262. h3. Writing a Migration
  263. Once you have created your migration using one of the generators it's time to
  264. get to work!
  265. h4. Creating a Table
  266. Migration method +create_table+ will be one of your workhorses. A typical use
  267. would be
  268. <ruby>
  269. create_table :products do |t|
  270. t.string :name
  271. end
  272. </ruby>
  273. which creates a +products+ table with a column called +name+ (and as discussed
  274. below, an implicit +id+ column).
  275. The object yielded to the block allows you to create columns on the table. There
  276. are two ways of doing it. The first (traditional) form looks like
  277. <ruby>
  278. create_table :products do |t|
  279. t.column :name, :string, :null => false
  280. end
  281. </ruby>
  282. The second form, the so called "sexy" migration, drops the somewhat redundant
  283. +column+ method. Instead, the +string+, +integer+, etc. methods create a column
  284. of that type. Subsequent parameters are the same.
  285. <ruby>
  286. create_table :products do |t|
  287. t.string :name, :null => false
  288. end
  289. </ruby>
  290. By default, +create_table+ will create a primary key called +id+. You can change
  291. the name of the primary key with the +:primary_key+ option (don't forget to
  292. update the corresponding model) or, if you don't want a primary key at all (for
  293. example for a HABTM join table), you can pass the option +:id => false+. If you
  294. need to pass database specific options you can place an SQL fragment in the
  295. +:options+ option. For example,
  296. <ruby>
  297. create_table :products, :options => "ENGINE=BLACKHOLE" do |t|
  298. t.string :name, :null => false
  299. end
  300. </ruby>
  301. will append +ENGINE=BLACKHOLE+ to the SQL statement used to create the table
  302. (when using MySQL, the default is +ENGINE=InnoDB+).
  303. h4. Changing Tables
  304. A close cousin of +create_table+ is +change_table+, used for changing existing
  305. tables. It is used in a similar fashion to +create_table+ but the object yielded
  306. to the block knows more tricks. For example
  307. <ruby>
  308. change_table :products do |t|
  309. t.remove :description, :name
  310. t.string :part_number
  311. t.index :part_number
  312. t.rename :upccode, :upc_code
  313. end
  314. </ruby>
  315. removes the +description+ and +name+ columns, creates a +part_number+ string
  316. column and adds an index on it. Finally it renames the +upccode+ column.
  317. h4. Special Helpers
  318. Active Record provides some shortcuts for common functionality. It is for
  319. example very common to add both the +created_at+ and +updated_at+ columns and so
  320. there is a method that does exactly that:
  321. <ruby>
  322. create_table :products do |t|
  323. t.timestamps
  324. end
  325. </ruby>
  326. will create a new products table with those two columns (plus the +id+ column)
  327. whereas
  328. <ruby>
  329. change_table :products do |t|
  330. t.timestamps
  331. end
  332. </ruby>
  333. adds those columns to an existing table.
  334. Another helper is called +references+ (also available as +belongs_to+). In its
  335. simplest form it just adds some readability.
  336. <ruby>
  337. create_table :products do |t|
  338. t.references :category
  339. end
  340. </ruby>
  341. will create a +category_id+ column of the appropriate type. Note that you pass
  342. the model name, not the column name. Active Record adds the +_id+ for you. If
  343. you have polymorphic +belongs_to+ associations then +references+ will add both
  344. of the columns required:
  345. <ruby>
  346. create_table :products do |t|
  347. t.references :attachment, :polymorphic => {:default => 'Photo'}
  348. end
  349. </ruby>
  350. will add an +attachment_id+ column and a string +attachment_type+ column with
  351. a default value of 'Photo'.
  352. NOTE: The +references+ helper does not actually create foreign key constraints
  353. for you. You will need to use +execute+ or a plugin that adds "foreign key
  354. support":#active-record-and-referential-integrity.
  355. If the helpers provided by Active Record aren't enough you can use the +execute+
  356. method to execute arbitrary SQL.
  357. For more details and examples of individual methods, check the API documentation,
  358. in particular the documentation for
  359. "<tt>ActiveRecord::ConnectionAdapters::SchemaStatements</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html
  360. (which provides the methods available in the +up+ and +down+ methods),
  361. "<tt>ActiveRecord::ConnectionAdapters::TableDefinition</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html
  362. (which provides the methods available on the object yielded by +create_table+)
  363. and
  364. "<tt>ActiveRecord::ConnectionAdapters::Table</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Table.html
  365. (which provides the methods available on the object yielded by +change_table+).
  366. h4. Using the +change+ Method
  367. The +change+ method removes the need to write both +up+ and +down+ methods in
  368. those cases that Rails know how to revert the changes automatically. Currently,
  369. the +change+ method supports only these migration definitions:
  370. * +add_column+
  371. * +add_index+
  372. * +add_timestamps+
  373. * +create_table+
  374. * +remove_timestamps+
  375. * +rename_column+
  376. * +rename_index+
  377. * +rename_table+
  378. If you're going to need to use any other methods, you'll have to write the
  379. +up+ and +down+ methods instead of using the +change+ method.
  380. h4. Using the +up+/+down+ Methods
  381. The +down+ method of your migration should revert the transformations done by
  382. the +up+ method. In other words, the database schema should be unchanged if you
  383. do an +up+ followed by a +down+. For example, if you create a table in the +up+
  384. method, you should drop it in the +down+ method. It is wise to reverse the
  385. transformations in precisely the reverse order they were made in the +up+
  386. method. For example,
  387. <ruby>
  388. class ExampleMigration < ActiveRecord::Migration
  389. def up
  390. create_table :products do |t|
  391. t.references :category
  392. end
  393. #add a foreign key
  394. execute <<-SQL
  395. ALTER TABLE products
  396. ADD CONSTRAINT fk_products_categories
  397. FOREIGN KEY (category_id)
  398. REFERENCES categories(id)
  399. SQL
  400. add_column :users, :home_page_url, :string
  401. rename_column :users, :email, :email_address
  402. end
  403. def down
  404. rename_column :users, :email_address, :email
  405. remove_column :users, :home_page_url
  406. execute <<-SQL
  407. ALTER TABLE products
  408. DROP FOREIGN KEY fk_products_categories
  409. SQL
  410. drop_table :products
  411. end
  412. end
  413. </ruby>
  414. Sometimes your migration will do something which is just plain irreversible; for
  415. example, it might destroy some data. In such cases, you can raise
  416. +ActiveRecord::IrreversibleMigration+ from your +down+ method. If someone tries
  417. to revert your migration, an error message will be displayed saying that it
  418. can't be done.
  419. h3. Running Migrations
  420. Rails provides a set of rake tasks to work with migrations which boil down to
  421. running certain sets of migrations.
  422. The very first migration related rake task you will use will probably be
  423. +rake db:migrate+. In its most basic form it just runs the +up+ or +change+
  424. method for all the migrations that have not yet been run. If there are
  425. no such migrations, it exits. It will run these migrations in order based
  426. on the date of the migration.
  427. Note that running the +db:migrate+ also invokes the +db:schema:dump+ task, which
  428. will update your db/schema.rb file to match the structure of your database.
  429. If you specify a target version, Active Record will run the required migrations
  430. (up, down or change) until it has reached the specified version. The version
  431. is the numerical prefix on the migration's filename. For example, to migrate
  432. to version 20080906120000 run
  433. <shell>
  434. $ rake db:migrate VERSION=20080906120000
  435. </shell>
  436. If version 20080906120000 is greater than the current version (i.e., it is
  437. migrating upwards), this will run the +up+ method on all migrations up to and
  438. including 20080906120000, and will not execute any later migrations. If
  439. migrating downwards, this will run the +down+ method on all the migrations
  440. down to, but not including, 20080906120000.
  441. h4. Rolling Back
  442. A common task is to rollback the last migration, for example if you made a
  443. mistake in it and wish to correct it. Rather than tracking down the version
  444. number associated with the previous migration you can run
  445. <shell>
  446. $ rake db:rollback
  447. </shell>
  448. This will run the +down+ method from the latest migration. If you need to undo
  449. several migrations you can provide a +STEP+ parameter:
  450. <shell>
  451. $ rake db:rollback STEP=3
  452. </shell>
  453. will run the +down+ method from the last 3 migrations.
  454. The +db:migrate:redo+ task is a shortcut for doing a rollback and then migrating
  455. back up again. As with the +db:rollback+ task, you can use the +STEP+ parameter
  456. if you need to go more than one version back, for example
  457. <shell>
  458. $ rake db:migrate:redo STEP=3
  459. </shell>
  460. Neither of these Rake tasks do anything you could not do with +db:migrate+. They
  461. are simply more convenient, since you do not need to explicitly specify the
  462. version to migrate to.
  463. h4. Resetting the database
  464. The +rake db:reset+ task will drop the database, recreate it and load the
  465. current schema into it.
  466. NOTE: This is not the same as running all the migrations - see the section on
  467. "schema.rb":#schema-dumping-and-you.
  468. h4. Running specific migrations
  469. If you need to run a specific migration up or down, the +db:migrate:up+ and
  470. +db:migrate:down+ tasks will do that. Just specify the appropriate version and
  471. the corresponding migration will have its +up+ or +down+ method invoked, for
  472. example,
  473. <shell>
  474. $ rake db:migrate:up VERSION=20080906120000
  475. </shell>
  476. will run the +up+ method from the 20080906120000 migration. These tasks still
  477. check whether the migration has already run, so for example +db:migrate:up
  478. VERSION=20080906120000+ will do nothing if Active Record believes that
  479. 20080906120000 has already been run.
  480. h4. Changing the output of running migrations
  481. By default migrations tell you exactly what they're doing and how long it took.
  482. A migration creating a table and adding an index might produce output like this
  483. <shell>
  484. == CreateProducts: migrating =================================================
  485. -- create_table(:products)
  486. -> 0.0028s
  487. == CreateProducts: migrated (0.0028s) ========================================
  488. </shell>
  489. Several methods are provided in migrations that allow you to control all this:
  490. |_.Method |_.Purpose|
  491. |suppress_messages |Takes a block as an argument and suppresses any output
  492. generated by the block.|
  493. |say |Takes a message argument and outputs it as is. A second
  494. boolean argument can be passed to specify whether to
  495. indent or not.|
  496. |say_with_time |Outputs text along with how long it took to run its
  497. block. If the block returns an integer it assumes it
  498. is the number of rows affected.|
  499. For example, this migration
  500. <ruby>
  501. class CreateProducts < ActiveRecord::Migration
  502. def change
  503. suppress_messages do
  504. create_table :products do |t|
  505. t.string :name
  506. t.text :description
  507. t.timestamps
  508. end
  509. end
  510. say "Created a table"
  511. suppress_messages {add_index :products, :name}
  512. say "and an index!", true
  513. say_with_time 'Waiting for a while' do
  514. sleep 10
  515. 250
  516. end
  517. end
  518. end
  519. </ruby>
  520. generates the following output
  521. <shell>
  522. == CreateProducts: migrating =================================================
  523. -- Created a table
  524. -> and an index!
  525. -- Waiting for a while
  526. -> 10.0013s
  527. -> 250 rows
  528. == CreateProducts: migrated (10.0054s) =======================================
  529. </shell>
  530. If you want Active Record to not output anything, then running +rake db:migrate
  531. VERBOSE=false+ will suppress all output.
  532. h3. Using Models in Your Migrations
  533. When creating or updating data in a migration it is often tempting to use one of
  534. your models. After all, they exist to provide easy access to the underlying
  535. data. This can be done, but some caution should be observed.
  536. For example, problems occur when the model uses database columns which are (1)
  537. not currently in the database and (2) will be created by this or a subsequent
  538. migration.
  539. Consider this example, where Alice and Bob are working on the same code base
  540. which contains a +Product+ model:
  541. Bob goes on vacation.
  542. Alice creates a migration for the +products+ table which adds a new column and
  543. initializes it. She also adds a validation to the +Product+ model for the new
  544. column.
  545. <ruby>
  546. # db/migrate/20100513121110_add_flag_to_product.rb
  547. class AddFlagToProduct < ActiveRecord::Migration
  548. def change
  549. add_column :products, :flag, :boolean
  550. Product.all.each do |product|
  551. product.update_attributes!(:flag => 'false')
  552. end
  553. end
  554. end
  555. </ruby>
  556. <ruby>
  557. # app/model/product.rb
  558. class Product < ActiveRecord::Base
  559. validates :flag, :presence => true
  560. end
  561. </ruby>
  562. Alice adds a second migration which adds and initializes another column to the
  563. +products+ table and also adds a validation to the +Product+ model for the new
  564. column.
  565. <ruby>
  566. # db/migrate/20100515121110_add_fuzz_to_product.rb
  567. class AddFuzzToProduct < ActiveRecord::Migration
  568. def change
  569. add_column :products, :fuzz, :string
  570. Product.all.each do |product|
  571. product.update_attributes! :fuzz => 'fuzzy'
  572. end
  573. end
  574. end
  575. </ruby>
  576. <ruby>
  577. # app/model/product.rb
  578. class Product < ActiveRecord::Base
  579. validates :flag, :fuzz, :presence => true
  580. end
  581. </ruby>
  582. Both migrations work for Alice.
  583. Bob comes back from vacation and:
  584. # Updates the source - which contains both migrations and the latests version of
  585. the Product model.
  586. # Runs outstanding migrations with +rake db:migrate+, which
  587. includes the one that updates the +Product+ model.
  588. The migration crashes because when the model attempts to save, it tries to
  589. validate the second added column, which is not in the database when the _first_
  590. migration runs:
  591. <plain>
  592. rake aborted!
  593. An error has occurred, this and all later migrations canceled:
  594. undefined method `fuzz' for #<Product:0x000001049b14a0>
  595. </plain>
  596. A fix for this is to create a local model within the migration. This keeps rails
  597. from running the validations, so that the migrations run to completion.
  598. When using a faux model, it's a good idea to call
  599. +Product.reset_column_information+ to refresh the +ActiveRecord+ cache for the
  600. +Product+ model prior to updating data in the database.
  601. If Alice had done this instead, there would have been no problem:
  602. <ruby>
  603. # db/migrate/20100513121110_add_flag_to_product.rb
  604. class AddFlagToProduct < ActiveRecord::Migration
  605. class Product < ActiveRecord::Base
  606. end
  607. def change
  608. add_column :products, :flag, :integer
  609. Product.reset_column_information
  610. Product.all.each do |product|
  611. product.update_attributes!(:flag => false)
  612. end
  613. end
  614. end
  615. </ruby>
  616. <ruby>
  617. # db/migrate/20100515121110_add_fuzz_to_product.rb
  618. class AddFuzzToProduct < ActiveRecord::Migration
  619. class Product < ActiveRecord::Base
  620. end
  621. def change
  622. add_column :products, :fuzz, :string
  623. Product.reset_column_information
  624. Product.all.each do |product|
  625. product.update_attributes!(:fuzz => 'fuzzy')
  626. end
  627. end
  628. end
  629. </ruby>
  630. h3. Schema Dumping and You
  631. h4. What are Schema Files for?
  632. Migrations, mighty as they may be, are not the authoritative source for your
  633. database schema. That role falls to either +db/schema.rb+ or an SQL file which
  634. Active Record generates by examining the database. They are not designed to be
  635. edited, they just represent the current state of the database.
  636. There is no need (and it is error prone) to deploy a new instance of an app by
  637. replaying the entire migration history. It is much simpler and faster to just
  638. load into the database a description of the current schema.
  639. For example, this is how the test database is created: the current development
  640. database is dumped (either to +db/schema.rb+ or +db/structure.sql+) and then
  641. loaded into the test database.
  642. Schema files are also useful if you want a quick look at what attributes an
  643. Active Record object has. This information is not in the model's code and is
  644. frequently spread across several migrations, but the information is nicely
  645. summed up in the schema file. The
  646. "annotate_models":https://github.com/ctran/annotate_models gem automatically
  647. adds and updates comments at the top of each model summarizing the schema if
  648. you desire that functionality.
  649. h4. Types of Schema Dumps
  650. There are two ways to dump the schema. This is set in +config/application.rb+ by
  651. the +config.active_record.schema_format+ setting, which may be either +:sql+ or
  652. +:ruby+.
  653. If +:ruby+ is selected then the schema is stored in +db/schema.rb+. If you look
  654. at this file you'll find that it looks an awful lot like one very big migration:
  655. <ruby>
  656. ActiveRecord::Schema.define(:version => 20080906171750) do
  657. create_table "authors", :force => true do |t|
  658. t.string "name"
  659. t.datetime "created_at"
  660. t.datetime "updated_at"
  661. end
  662. create_table "products", :force => true do |t|
  663. t.string "name"
  664. t.text "description"
  665. t.datetime "created_at"
  666. t.datetime "updated_at"
  667. t.string "part_number"
  668. end
  669. end
  670. </ruby>
  671. In many ways this is exactly what it is. This file is created by inspecting the
  672. database and expressing its structure using +create_table+, +add_index+, and so
  673. on. Because this is database-independent, it could be loaded into any database
  674. that Active Record supports. This could be very useful if you were to distribute
  675. an application that is able to run against multiple databases.
  676. There is however a trade-off: +db/schema.rb+ cannot express database specific
  677. items such as foreign key constraints, triggers, or stored procedures. While in
  678. a migration you can execute custom SQL statements, the schema dumper cannot
  679. reconstitute those statements from the database. If you are using features like
  680. this, then you should set the schema format to +:sql+.
  681. Instead of using Active Record's schema dumper, the database's structure will be
  682. dumped using a tool specific to the database (via the +db:structure:dump+ Rake task)
  683. into +db/structure.sql+. For example, for the PostgreSQL RDBMS, the
  684. +pg_dump+ utility is used. For MySQL, this file will contain the output of +SHOW
  685. CREATE TABLE+ for the various tables. Loading these schemas is simply a question
  686. of executing the SQL statements they contain. By definition, this will create a
  687. perfect copy of the database's structure. Using the +:sql+ schema format will,
  688. however, prevent loading the schema into a RDBMS other than the one used to
  689. create it.
  690. h4. Schema Dumps and Source Control
  691. Because schema dumps are the authoritative source for your database schema, it
  692. is strongly recommended that you check them into source control.
  693. h3. Active Record and Referential Integrity
  694. The Active Record way claims that intelligence belongs in your models, not in
  695. the database. As such, features such as triggers or foreign key constraints,
  696. which push some of that intelligence back into the database, are not heavily
  697. used.
  698. Validations such as +validates :foreign_key, :uniqueness => true+ are one way in
  699. which models can enforce data integrity. The +:dependent+ option on associations
  700. allows models to automatically destroy child objects when the parent is
  701. destroyed. Like anything which operates at the application level, these cannot
  702. guarantee referential integrity and so some people augment them with foreign key
  703. constraints in the database.
  704. Although Active Record does not provide any tools for working directly with such
  705. features, the +execute+ method can be used to execute arbitrary SQL. You could
  706. also use some plugin like "foreigner":https://github.com/matthuhiggins/foreigner
  707. which add foreign key support to Active Record (including support for dumping
  708. foreign keys in +db/schema.rb+).