[Rails]migrationで外部キーを設定する際に、参照先テーブルと異なるカラム名をつけたい場合


migration時に外部キーを設定する場合、referencesを使いますが、参照先テーブルと異なるカラム名をつけたい場合はどうしようと思い調べてみました。

Usersテーブルのuser_idを、Likesテーブルのuser_idとtarget_user_idの外部キーとして設定したい場合のサンプル

  • migration
# db/migrate/xxxx_create_likes.rb

class CreateLike < ActiveRecord::Migration
  def up
    create_table :likes do |t|
      t.references :user
      t.integer :target_user_id, :null => false  # references を使わず指定

      t.timestamps
    end

    add_index :like, :user_id
    add_index :like, :target_user_id
  end

  def down
    drop_table :likes
  end
end
  • Userモデルのhas_manyにclass_name, foreign_keyを指定
# app/models/like.rb

class User < ActiveRecord::Base
  has_many :to_like_users, :class_name => "Like", :foreign_key => 'user_id' # :class_name, :foreign_keyを指定
  has_many :from_like_users, :class_name => "Like", :foreign_key => 'target_user_id'  # :class_name, :foreign_keyを指定
end
  • Likeモデルのbelong_toにclass_nameを指定
# app/models/like.rb

class Like < ActiveRecord::Base
  belongs_to :user
  belongs_to :target_user, :class_name => "User"  # :class_nameを指定
end

migrationファイルでは、target_user_idの設定にreferencesを使用せず、integerで指定

t.integer :target_user_id, :null => false

Likeモデルのbelongs_toのオプションにclass_nameでUserを指定することで、target_userを関連付けることができました。

belongs_to :target_user, :class_name => "User"

参考