Active record so sánh với application record năm 2024
Migrations are a convenient way to alter your database schema over time in a consistent way. They use a Ruby DSL so that you don't have to write SQL by hand, allowing your schema and changes to be database independent. Show You can think of each migration as being a new 'version' of the database. A schema starts off with nothing in it, and each migration modifies it to add or remove tables, columns, or entries. Active Record knows how to update your schema along this timeline, bringing it from whatever point it is in the history to the latest version. Active Record will also update your
9 file to match the up-to-date structure of your database. Here's an example of a migration:
This migration adds a table called
0 with a string column called
1 and a text column called
2. A primary key column called
3 will also be added implicitly, as it's the default primary key for all Active Record models. The
4 macro adds two columns,
5 and
6. These special columns are automatically managed by Active Record if they exist. Note that we define the change that we want to happen moving forward in time. Before this migration is run, there will be no table. After, the table will exist. Active Record knows how to reverse this migration as well: if we roll this migration back, it will remove the table. On databases that support transactions with statements that change the schema, each migration is wrapped in a transaction. If the database does not support this then when a migration fails the parts of it that succeeded will not be rolled back. You will have to rollback the changes that were made by hand. There are certain queries that can't run inside a transaction. If your adapter supports DDL transactions you can use
7 to disable them for a single migration. If you wish for a migration to do something that Active Record doesn't know how to reverse, you can use
8:
This migration will change the type of the
9 column to a string, or back to an integer when the migration is reverted. Notice the block being passed to
0 and
1 respectively. Alternatively, you can use
2 and
3 instead of
4:
Migrations are stored as files in the
5 directory, one for each migration class. The name of the file is of the form
6, that is to say a UTC timestamp identifying the migration followed by an underscore followed by the name of the migration. The name of the migration class (CamelCased version) should match the latter part of the file name. For example
7 should define class
8 and
9 should define
0. Rails uses this timestamp to determine which migration should be run and in what order, so if you're copying a migration from another application or generate a file yourself, be aware of its position in the order. Of course, calculating timestamps is no fun, so Active Record provides a generator to handle making it for you:
This will create an appropriately named empty migration:
This generator can do much more than prepend a timestamp to the file name. Based on naming conventions and additional (optional) arguments it can also start fleshing out the migration. If the migration name is of the form "AddColumnToTable" or "RemoveColumnFromTable" and is followed by a list of column names and types then a migration containing the appropriate and statements will be created.
This will generate the following migration:
If you'd like to add an index on the new column, you can do that as well.
This will generate the appropriate and statements:
You are not limited to one magically generated column. For example:
Will generate a schema migration which adds two additional columns to the
0 table.
0 Similarly, you can generate a migration to remove a column from the command line:
1 This generates the appropriate statements:
2 If the migration name is of the form "CreateXXX" and is followed by a list of column names and types then a migration creating the table XXX with the columns listed will be generated. For example:
3 generates
4 As always, what has been generated for you is just a starting point. You can add or remove from it as you see fit by editing the
7 file. Also, the generator accepts column type as
8 (also available as
9). For example,
5 generates the following call:
6 This migration will create a
1 column. are a shorthand for creating columns, indexes, foreign keys, or even polymorphic association columns. There is also a generator which will produce join tables if
2 is part of the name:
7 will produce the following migration:
8 The model, resource, and scaffold generators will create migrations appropriate for adding a new model. This migration will already contain instructions for creating the relevant table. If you tell Rails what columns you want, then statements for adding these columns will also be created. For example, running:
9 This will create a migration that looks like this:
You can append as many column name/type pairs as you want. Some commonly used can be passed directly on the command line. They are enclosed by curly braces and follow the field type: For instance, running:
1 will produce a migration that looks like this
2 Have a look at the generators help output (
Once you have created your migration using one of the generators it's time to get to work! The method is one of the most fundamental, but most of the time, will be generated for you from using a model, resource, or scaffold generator. A typical use would be
3 This method creates a
0 table with a column called
1. By default,
4 will implicitly create a primary key called
3 for you. You can change the name of the column with the
9 option, or pass an array to
9 for a composite primary key. If you don't want a primary key at all, you can pass the option
01. If you need to pass database-specific options you can place an SQL fragment in the
02 option. For example:
4 This will append
03 to the SQL statement used to create the table. An index can be created on the columns created within the
4 block by passing
05 or an options hash to the
06 option:
5 Also, you can pass the
07 option with any description for the table that will be stored in the database itself and can be viewed with database administration tools, such as MySQL Workbench or PgAdmin III. It's highly recommended to specify comments in migrations for applications with large databases as it helps people to understand the data model and generate documentation. Currently only the MySQL and PostgreSQL adapters support comments. The migration method creates an HABTM (has and belongs to many) join table. A typical use would be:
6 This migration will create a
09 table with two columns called
10 and
11. These columns have the option
12 set to
13 by default, meaning that you must provide a value in order to save a record to this table. This can be overridden by specifying the
14 option:
7 By default, the name of the join table comes from the union of the first two arguments provided to create_join_table, in alphabetical order. To customize the name of the table, provide a
15 option:
8 This ensure the name of the join table is
16 as requested. Also,
08 accepts a block, which you can use to add indices (which are not created by default) or any additional columns you so choose.
9 If you want to change an existing table in place, there is . It is used in a similar fashion to
4 but the object yielded inside the block has access to a number of special functions, for example:
0 This migration will remove the
2 and
1 columns, create a new string column called
22 and adds an index on it. Finally it renames the
23 column to
24. Similar to the
2 and
1 methods we covered , Rails also provides the migration method.
1 This changes the column
22 on products table to be a
29 field. The
27 command is irreversible. You should provide your own
8 migration, like we discussed . Besides
27, the and methods are used specifically to change a null constraint and default values of a column.
2 This sets
35 field on products to a
36 column and the default value of the
37 field from true to false. Both of these changes will only be applied to future transactions, any existing records do not apply. When setting the null constraint to true, this means that column will accept a null value, otherwise the
36 constraint is applied and a value must be passed in order to persist the record to the database. You could also write the above
34 migration as
40, but unlike the previous example, this would make your migration irreversible. Column modifiers can be applied when creating or changing a column:
For
1 or
27 there is no option for adding indexes. They need to be added separately using
4. Some adapters may support additional options; see the adapter specific API docs for further information.
51 and
45 cannot be specified via command line when generating migrations. The
0 method allows the creation of an appropriately named column acting as the connection between one or more associations.
3 This migration will create a
64 column in the users table. It creates an index for this column as well, unless explicitly told not to with the
65 option. The method
66 is an alias of
0.
4 The polymorphic option will create two columns on the taggings table which can be used for polymorphic associations:
68 and
69. A foreign key can be created with the
70 option.
5 For more
0 options, visit the . References can also be removed:
6 While it's not required, you might want to add foreign key constraints to .
7 This call adds a new constraint to the
73 table. The constraint guarantees that a row in the
74 table exists where the
3 column matches the
76. If the
77 column name cannot be derived from the
78 name, you can use the
79 option. Use the
9 option if the referenced primary key is not
81. For example, to add a foreign key on
82 referencing
83:
8 This will add a constraint to the
73 table that guarantees a row in the
74 table exists where the
86 column matches the
82 field. Several other options such as
1,
89,
90,
91, and
92 are supported by
72. Foreign keys can also be removed using :
9 Active Record only supports single column foreign keys.
95 and
96 are required to use composite foreign keys. See . Sometimes a single column's value isn't enough to uniquely identify every row of a table, but a combination of two or more columns does uniquely identify it. This can be the case when using a legacy database schema without a single
3 column as a primary key, or when altering schemas for sharding or multitenancy. You can create a table with a composite primary key by passing the
9 option to
4 with an array value:
0 Tables with composite primary keys require passing array values rather than integer IDs to many methods. See also the Active Record Querying guide to learn more. If the helpers provided by Active Record aren't enough you can use the method to execute arbitrary SQL:
1 For more details and examples of individual methods, check the API documentation. In particular the documentation for
01, which provides the methods available in the
4,
2 and
3 methods. For methods available regarding the object yielded by
4, see
06. And for the object yielded by
18, see
08. The
4 method is the primary way of writing migrations. It works for the majority of cases in which Active Record knows how to reverse a migration's actions automatically. Below are some of the actions that
4 supports:
is also reversible, as long as the block only calls reversible operations like the ones listed above. If you're going to need to use any other methods, you should use
8 or write the
2 and
3 methods instead of using the
4 method. Complex migrations may require processing that Active Record doesn't know how to reverse. You can use to specify what to do when running a migration and what else to do when reverting it. For example:
2 Using
8 will ensure that the instructions are executed in the right order too. If the previous example migration is reverted, the
3 block will be run after the
53 column is removed and before the
54 table is dropped. You can also use the old style of migration using
2 and
3 methods instead of the
4 method. The
2 method should describe the transformation you'd like to make to your schema, and the
3 method of your migration should revert the transformations done by the
2 method. In other words, the database schema should be unchanged if you do an
2 followed by a
3. For example, if you create a table in the
2 method, you should drop it in the
3 method. It is wise to perform the transformations in precisely the reverse order they were made in the
2 method. The example in the
8 section is equivalent to:
3 Sometimes your migration will do something which is just plain irreversible; for example, it might destroy some data. In such cases, you can raise
69 in your
3 block. If someone tries to revert your migration, an error message will be displayed saying that it can't be done. You can use Active Record's ability to rollback migrations using the method:
4 The
71 method also accepts a block of instructions to reverse. This could be useful to revert selected parts of previous migrations. For example, let's imagine that
73 is committed and it is later decided that a Distributors view is no longer needed.
5 The same migration could also have been written without using
71 but this would have involved a few more steps:
This is all taken care of by
71. Rails provides a set of commands to run certain sets of migrations. The very first migration related rails command you will use will probably be
82. In its most basic form it just runs the
4 or
2 method for all the migrations that have not yet been run. If there are no such migrations, it exits. It will run these migrations in order based on the date of the migration. Note that running the
85 command also invokes the
86 command, which will update your
9 file to match the structure of your database. If you specify a target version, Active Record will run the required migrations (change, up, down) until it has reached the specified version. The version is the numerical prefix on the migration's filename. For example, to migrate to version 20080906120000 run:
6 If version 20080906120000 is greater than the current version (i.e., it is migrating upwards), this will run the
4 (or
3 method on all the migrations down to, but not including, 20080906120000. A common task is to rollback the last migration. For example, if you made a mistake in it and wish to correct it. Rather than tracking down the version number associated with the previous migration you can run: This will rollback the latest migration, either by reverting the
4 method or by running the
3 method. If you need to undo several migrations you can provide a
93 parameter:
7 The last 3 migrations will be reverted. The
94 command is a shortcut for doing a rollback and then migrating back up again. As with the
95 command, you can use the
93 parameter if you need to go more than one version back, for example:
8 Neither of these rails commands do anything you could not do with
85. They are there for convenience, since you do not need to explicitly specify the version to migrate to. The
98 command will create the database, load the schema, and initialize it with the seed data. The
99 command is similar to
98, but it operates idempotently.
Once the database, tables, and seed data are all established, the command will not try to reload the seed data, even if the previously loaded seed data or the existing seed file have been altered or deleted. To reload the seed data, you can manually run
02. The
03 command will drop the database and set it up again. This is functionally equivalent to
04. This is not the same as running all the migrations. It will only use the contents of the current
9 or
06 file. If a migration can't be rolled back,
03 may not help you. To find out more about dumping the schema see section. If you need to run a specific migration up or down, the
08 and
09 commands will do that. Just specify the appropriate version and the corresponding migration will have its
4,
2 or
3 method invoked, for example:
9 By running this command the
4 method (or the
2 method) will be executed for the migration with the version "20080906120000". First, this command will check whether the migration exists and if it has already been performed and will do nothing if so. If the version specified does not exist, Rails will throw an exception.
0 By default running
82 will run in the
16 environment. To run migrations against another environment you can specify it using the
17 environment variable while running the command. For example to run migrations against the
18 environment you could run:
1 By default migrations tell you exactly what they're doing and how long it took. A migration creating a table and adding an index might produce output like this
2 Several methods are provided in migrations that allow you to control all this: Method Purpose Takes a block as an argument and suppresses any output generated by the block. Takes a message argument and outputs it as is. A second boolean argument can be passed to specify whether to indent or not. Outputs text along with how long it took to run its block. If the block returns an integer it assumes it is the number of rows affected. For example, take the following migration:
3 This will generate the following output:
4 If you want Active Record to not output anything, then running
22 will suppress all output. Occasionally you will make a mistake when writing a migration. If you have already run the migration, then you cannot just edit the migration and run the migration again: Rails thinks it has already run the migration and so will do nothing when you run
82. You must rollback the migration (for example with
24), edit your migration, and then run
82 to run the corrected version. In general, editing existing migrations is not a good idea. You will be creating extra work for yourself and your co-workers and cause major headaches if the existing version of the migration has already been run on production machines. Instead, you should write a new migration that performs the changes you require. Editing a freshly generated migration that has not yet been committed to source control (or, more generally, which has not been propagated beyond your development machine) is relatively harmless. The
71 method can be helpful when writing a new migration to undo previous migrations in whole or in part (see above). Migrations, mighty as they may be, are not the authoritative source for your database schema. Your database remains the source of truth. By default, Rails generates
9 which attempts to capture the current state of your database schema. It tends to be faster and less error prone to create a new instance of your application's database by loading the schema file via
28 than it is to replay the entire migration history. may fail to apply correctly if those migrations use changing external dependencies or rely on application code which evolves separately from your migrations. Schema files are also useful if you want a quick look at what attributes an Active Record object has. This information is not in the model's code and is frequently spread across several migrations, but the information is nicely summed up in the schema file. The format of the schema dump generated by Rails is controlled by the setting defined in
30. By default, the format is
31, or alternatively can be set to
32. When
31 is selected, then the schema is stored in
9. If you look at this file you'll find that it looks an awful lot like one very big migration:
5 In many ways this is exactly what it is. This file is created by inspecting the database and expressing its structure using
4,
4, and so on. However,
9 cannot express everything your database may support such as triggers, sequences, stored procedures, etc. While migrations may use
95 to create database constructs that are not supported by the Ruby migration DSL, these constructs may not be able to be reconstituted by the schema dumper. If you are using features like these, you should set the schema format to
32 in order to get an accurate schema file that is useful to create new database instances. When the schema format is set to
32, the database structure will be dumped using a tool specific to the database into
06. For example, for PostgreSQL, the
44 utility is used. For MySQL and MariaDB, this file will contain the output of
45 for the various tables. To load the schema from
06, run
28. Loading this file is done by executing the SQL statements it contains. By definition, this will create a perfect copy of the database's structure. Because schema files are commonly used to create new databases, it is strongly recommended that you check your schema file into source control. Merge conflicts can occur in your schema file when two branches modify schema. To resolve these conflicts run
82 to regenerate the schema file. Newly generated Rails apps will already have the migrations folder included in the git tree, so all you have to do is be sure to add any new migrations you add and commit them. The Active Record way claims that intelligence belongs in your models, not in the database. As such, features such as triggers or constraints, which push some of that intelligence back into the database, are not recommended. Validations such as
49 are one way in which models can enforce data integrity. The
50 option on associations allows models to automatically destroy child objects when the parent is destroyed. Like anything which operates at the application level, these cannot guarantee referential integrity and so some people augment them with in the database. Although Active Record does not provide all the tools for working directly with such features, the
95 method can be used to execute arbitrary SQL. The main purpose of Rails' migration feature is to issue commands that modify the schema using a consistent process. Migrations can also be used to add or modify data. This is useful in an existing database that can't be destroyed and recreated, such as a production database.
6 To add initial data after a database is created, Rails has a built-in 'seeds' feature that speeds up the process. This is especially useful when reloading the database frequently in development and test environments, or when setting up initial data for production. To get started with this feature, open up
52 and add some Ruby code, then run
02. The code here should be idempotent so that it can be executed at any point in every environment.
7 This is generally a much cleaner way to set up the database of a blank application. The
9 or
06 is a snapshot of the current state of your database and is the authoritative source for rebuilding that database. This makes it possible to delete or prune old migration files. When you delete migration files in the
56 directory, any environment where
82 was run when those files still existed will hold a reference to the migration timestamp specific to them inside an internal Rails database table named
58. This table is used to keep track of whether migrations have been executed in a specific environment. If you run the
59 command, which displays the status (up or down) of each migration, you should see
60 displayed next to any deleted migration file which was once executed on a specific environment but can no longer be found in the
56 directory. There's a caveat, though with Engines. Rake tasks to install migrations from engines are idempotent, meaning they will have the same result no matter how many times they are called. Migrations present in the parent application due to a previous installation are skipped, and missing ones are copied with a new leading timestamp. If you deleted old engine migrations and ran the install task again, you'd get new files with new timestamps, and
85 would attempt to run them again. Thus, you generally want to preserve migrations coming from engines. They have a special comment like this:
8 FeedbackYou're encouraged to help improve the quality of this guide. Please contribute if you see any typos or factual errors. To get started, you can read our section. You may also find incomplete content or stuff that is not up to date. Please do add any missing documentation for main. Make sure to check Edge Guides first to verify if the issues are already fixed or not on the main branch. Check the Ruby on Rails Guides Guidelines for style and conventions. If for whatever reason you spot something to fix but cannot patch it yourself, please open an issue. And last but not least, any kind of discussion regarding Ruby on Rails documentation is very welcome on the official Ruby on Rails Forum. |