Rails 4.2 以後開始支援 database 的 foreign key,很好的文章:
https://robots.thoughtbot.com/referential-integrity-with-foreign-keys
我們會用
```rb
class User < ActiveRecord::Base
has_many :posts, dependent: :destroy
end
class Post < ActiveRecord::Base
belongs_to :user
validates :user, presence: true
end
```
這種做法來確保 post 有 user,看似沒問題但這些 validation 都在 rails 的 application 層級,而 rails 提供了很多方式讓你跳過這些 validations 和 callbacks,所以是不可信任的。ex:
User.delete_all 會跳過 `dependent: :destroy` callback
更別提我們常常連 `dependent: :destroy` callback 都忘記加(oops~)
所以應該讓 database 加上這個限制確保我們不會不小心搞爆這些資料
```rb
def change
add_foreign_key :posts, :users
end
```
另外也可以讓 database 幫我們做到 `dependent: destroy` 一樣的事情
```rb
add_foreign_key :posts, :users, on_delete: :cascade
```
會產生 SQL (postgres):
```sql
ALTER TABLE `posts`
ADD CONSTRAINT `posts_user_id_fk`
FOREIGN KEY (`user_id`) REFERENCES `users`(id)
ON DELETE CASCADE;
```
Caveats:rails 的 Polymorphic associations 不適用
沒有留言:
張貼留言