Hello mọi người, lại là Tiến đây. Hôm nay mình sẽ chia sẻ mọi người chút thay đổi ở version Rails 7 mới nhất nhé.
Bài viết gốc trên trang blog của mình: https://tienvm.com/rails-7-bo-sung-option-ifexistsifnotexists-khi-themxoa-foreignkey-trong-migration
Rails 6.1 đã thêm hỗ trợ cho if_exists/if_not_exists
trên loại để add/remove column và mở rộng nó hơn nữa để hỗ trợ if_not_exists
trên add_index
và if_exists
trên remove_index
.
Để duy trì cùng một hành vi trên các rằng buộc add/remove của database, Rails 7 đã bổ sung hỗ trợ if_exists/if_not_exists
trên remove_foreign_key/add_foreign_key
trong migration.
Before Rails 7 ⛹️⛹️⛹️
Add foreign key 🤔
Giả sử chúng ta có 2 bảng Order
và User
, Order
sẽ thuộc về(belongs_to) một User
. Chúng ta sẽ thêm user_id
làm foreign_key vào bảng Order
. Thể hiện migration sẽ như sau:
classAddUserReferenceToOrder< ActiveRecord::Migration[6.0]
def change
add_foreign_key :orders,:users
end
end
Nhưng nếu bảng Order
đã có khóa ngoại user_id
đối với User
, migration sẽ raise lỗi ❌❌❌
rails db:migrate
==20210714080612 AddUserReferenceToOrder: migrating ================--add_foreign_key(:orders,:users)
rake aborted!
StandardError: An error has occurred,this and all later migrations canceled:PG::DuplicateObject:ERROR: constraint "fk_rails_11f1189a77"for relation "orders" already exists
Remove foreign key 🤔
Tương tự, nếu chúng ta cố gắng loại bỏ foreign_key user_id
trên bảng Order
nhưng nó không tồn tại ở bảng Order
thì cũng sẽ raise lỗi ❌❌❌
classRemoveProductReferenceFromOrder< ActiveRecord::Migration[6.0]
def change
remove_foreign_key :orders,:products
end
end
rails db:migrate
==20210714080712 RemoveProductReferenceFromOrder: migrating ================--remove_foreign_key(:orders,:products)
rake aborted!
StandardError: An error has occurred,this and all later migrations canceled:
Table 'orders' has no foreign key for products
In Rails 7 🤾🤾🤾
Để tránh các vấn đề trên và giữ mọi thứ được nhất quán. Team phát triển Rails đã bổ sung thêm option if_exists/if_not_exists
để remove_foreign_key/add_foreign_key
. Với sự thay đổi này, quá trình chạy migration bên dưới sẽ thành công và không gây ra bất kỳ lỗi nào
Add foreign key 🤤
classAddUserReferenceToOrder< ActiveRecord::Migration[6.0]
def change
add_foreign_key :orders,:users, if_not_exists:true
end
end
rails db:migrate
==20210714080612 AddUserReferenceToOrder: migrating ================--add_foreign_key(:orders,:users,{:if_not_exists=>true})->0.0151s
==20210714080612 AddUserReferenceToOrder:migrated(0.0153s)==================
Remove foreign key 🤤
classRemoveProductReferenceFromOrder< ActiveRecord::Migration[6.0]
def change
remove_foreign_key :orders,:products, if_exists:true
end
end
rails db:migrate
==20210714080712 RemoveProductReferenceFromOrder: migrating ================--remove_foreign_key(:orders,:products,{if_exists:true})->0.0118s
==20210714080712 RemoveProductReferenceFromOrder:migrated(0.0118s)================
mlem mlem….Hí hí 🤤🤤
Bạn có thể xem chi tiết thay đổi lại tại pull request của source Rails trên Github
Cảm ơn mọi người đã dành thời gian đọc bài viết của mình. Hãy like và up vote bài viết nếu thấy có ích. Đừng ngại để lại comment để chúng ta có thể tương tác và học tập lẫn nhau nhé :v
Follow blog cá nhân của mình tại đây: https://tienvm.com/ nhé.
Bạn có thể mời mình 1 cốc coffee tại Buy me a coffee để mình có động lực ra thêm những bài mới nhé :v
❤️ Thank you for reading and see you next posts ❤️
Nguồn: viblo.asia