Railsのbelongs_toによるバリデーションと外部キー制約って重複しているような気がする

表題のとおりなのですが。

class Post < ApplicationRecord
  belongs_to :user
end

↑のように書いたときに、Rails5からは自動でvalidation_presence_of :userとしたのと同じになります。postをバリデーションするときにuserの存在をチェックする必要があるので、userが未ロードであればクエリが発行されます。一度にたくさんのpostを保存するようなケースでN+1が発生して困った経験がある人もいるのではないでしょうか。

./bin/rails g model post user:references のようにした場合は、次のように外部キー制約とbelongs_toが両方定義された状態になりますね。

class CreatePosts < ActiveRecord::Migration[6.0]
  def change
    create_table :posts do |t|
      t.references :user, null: false, foreign_key: true

      t.timestamps
    end
  end
end
class Post < ApplicationRecord
  belongs_to :user
end

しかし、PostからUserへ外部キー制約を貼っていればvalidation_presence_of :userは不要では?という気がします。むしろ無駄にクエリが発行される分マイナスなような気もする。

次のようにすればOKではあるけれど、実際は必須なのにoptional: trueと書かなければいけないなのが大変微妙。

class Post < ApplicationRecord
  belongs_to :user, optional: true
end

と、ここまで書いていて気がついたけど論理削除のようなしくみを採用していた場合は外部キー制約では不十分ですね…とりあえず今回のケースではそれは考慮しないとします…><

このへん、みんなどのように解決しているのでしょうか?コメントほしいです(\( ⁰⊖⁰)/)

  1. 外部キーを使っておらず、belongs_toによるバリデーションを利用している
  2. Railsが生成するデフォルトのように、外部キーとbelongs_toによるバリデーションを両方使っている
  3. 外部キーのみ使用しており、belongs_toによるバリデーションはオフにしている
  4. その他