mirror of
https://github.com/jbranchaud/til
synced 2026-01-05 16:18:01 +00:00
Add Ensure Migrations Use The Latest Schema as a rails til
This commit is contained in:
@@ -10,7 +10,7 @@ smart people at [Hashrocket](http://hashrocket.com/).
|
|||||||
For a steady stream of TILs from a variety of rocketeers, checkout
|
For a steady stream of TILs from a variety of rocketeers, checkout
|
||||||
[til.hashrocket.com](https://til.hashrocket.com/).
|
[til.hashrocket.com](https://til.hashrocket.com/).
|
||||||
|
|
||||||
_812 TILs and counting..._
|
_813 TILs and counting..._
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -493,6 +493,7 @@ _812 TILs and counting..._
|
|||||||
- [Delete Paranoid Records](rails/delete-paranoid-records.md)
|
- [Delete Paranoid Records](rails/delete-paranoid-records.md)
|
||||||
- [Demodulize A Class Name](rails/demodulize-a-class-name.md)
|
- [Demodulize A Class Name](rails/demodulize-a-class-name.md)
|
||||||
- [Disambiguate Where In A Joined Relation](rails/disambiguate-where-in-a-joined-relation.md)
|
- [Disambiguate Where In A Joined Relation](rails/disambiguate-where-in-a-joined-relation.md)
|
||||||
|
- [Ensure Migrations Use The Latest Schema](rails/ensure-migrations-use-the-latest-schema.md)
|
||||||
- [Generating And Executing SQL](rails/generating-and-executing-sql.md)
|
- [Generating And Executing SQL](rails/generating-and-executing-sql.md)
|
||||||
- [Hash Slicing](rails/hash-slicing.md)
|
- [Hash Slicing](rails/hash-slicing.md)
|
||||||
- [Ignore Poltergeist JavaScript Errors](rails/ignore-poltergeist-javascript-errors.md)
|
- [Ignore Poltergeist JavaScript Errors](rails/ignore-poltergeist-javascript-errors.md)
|
||||||
|
|||||||
50
rails/ensure-migrations-use-the-latest-schema.md
Normal file
50
rails/ensure-migrations-use-the-latest-schema.md
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
# Ensure Migrations Use The Latest Schema
|
||||||
|
|
||||||
|
Real-world migrations in Rails apps can sometimes involve both schema changes
|
||||||
|
and data changes. For instance, if you are moving a column from one table to
|
||||||
|
another, you'll need to add a new column, move some data, and then delete the
|
||||||
|
old column.
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
// Assume the following are defined:
|
||||||
|
// GenericAuthor for table 'authors'
|
||||||
|
// GenericBook for table 'books'
|
||||||
|
|
||||||
|
def up
|
||||||
|
add_column :books, :genre, :string
|
||||||
|
|
||||||
|
GenericAuthor.find_each do |author|
|
||||||
|
book = GenericBook.find_by(author_id: author.id)
|
||||||
|
book.update!(genre: author.genre)
|
||||||
|
end
|
||||||
|
|
||||||
|
remove_column :authors, :genre
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
This migration looks straightforward, but you may find that no data actually
|
||||||
|
gets transferred to the `genre` column on `books`. This is because as a
|
||||||
|
performance optimization, Rails has cached the scema. Thus an `ActiveRecord`
|
||||||
|
modification like `book.update!` will be working off a version of the schema
|
||||||
|
that doesn't include `genre` as a column.
|
||||||
|
|
||||||
|
We can ensure `ActiveRecord` is using the latest column informtion for the
|
||||||
|
`books` table by calling
|
||||||
|
[`reset_column_information`](https://api.rubyonrails.org/classes/ActiveRecord/ModelSchema/ClassMethods.html#method-i-reset_column_information).
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
def up
|
||||||
|
add_column :books, :genre, :string
|
||||||
|
|
||||||
|
GenericBook.reset_column_information
|
||||||
|
|
||||||
|
GenericAuthor.find_each do |author|
|
||||||
|
book = GenericBook.find_by(author_id: author.id)
|
||||||
|
book.update!(genre: author.genre)
|
||||||
|
end
|
||||||
|
|
||||||
|
remove_column :authors, :genre
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
Now the update will work and `genre` will be set on `books`.
|
||||||
Reference in New Issue
Block a user