Gọi model class (VD: User.update_all(...)) trong migration nguy hiểm vì model thay đổi theo thời gian — migration cũ sẽ fail khi replay (setup fresh DB) vì model không còn method/association đó nữa.
Sai:
ruby
class BackfillUserRole < ActiveRecord::Migration[7.1]
def up
User.where(role: nil).update_all(role: "member") # nguy hiểm!
end
endĐúng — dùng anonymous model hoặc raw SQL:
ruby
class BackfillUserRole < ActiveRecord::Migration[7.1]
# Anonymous class chỉ biết schema hiện tại của migration này
class User < ApplicationRecord; end
def up
User.where(role: nil).update_all(role: "member")
end
end
# Hoặc đơn giản hơn:
def up
execute "UPDATE users SET role = 'member' WHERE role IS NULL"
endReferencing a model class (e.g. User.update_all(...)) in a migration is dangerous because the model evolves over time — old migrations break when replayed on a fresh DB because the model no longer has that method/association.
Wrong:
ruby
class BackfillUserRole < ActiveRecord::Migration[7.1]
def up
User.where(role: nil).update_all(role: "member") # dangerous!
end
endRight — use an anonymous model or raw SQL:
ruby
class BackfillUserRole < ActiveRecord::Migration[7.1]
# Anonymous class only knows the schema at the time of this migration
class User < ApplicationRecord; end
def up
User.where(role: nil).update_all(role: "member")
end
end
# Or simpler:
def up
execute "UPDATE users SET role = 'member' WHERE role IS NULL"
end