##解決したい問題
ユーザーと投稿を関連付けをしたく、postsテーブルにuser_idカラムを追加した。
しかし、別に新たなマイグレーションを実行するたびに、なぜかschema上で、user_idカラムが消えてしまう。
##最初は関連付けに関してあまり考えず進めていた
class AddUserIdToPosts < ActiveRecord::Migration[6.0]
def change
def change
add_column :posts, :user_id ,:integer
end
end
end
class Post < ApplicationRecord
belongs_to :user
<!---some long code--!>
class User < ApplicationRecord
has_many :posts
<!---some long code--!>
postsテーブルにuser_idカラムは追加しており、postモデルにbelongs_to :user
、
userモデルにhas_many :posts
の追加はしてある。
##belongs_to :user
この宣言は、postsテーブル上の対応する外部キーカラムと整合している必要がある!
具体的にはどうするのか?
Railsガイドに下記の説明の記載を発見。
カラムの種類としてreferences (belongs_to も可) を指定することができます。たとえば次のようになります。
$ rails generate migration AddUserRefToProducts user:references
上を実行すると以下が生成されます。
class AddUserRefToProducts < ActiveRecord::Migration[5.0]
def change
add_reference :products, :user, foreign_key: true
end
end
このマイグレーションを実行すると、user_idが作成され、適切なインデックスが追加されます。
reference
カラムとforeign_key
外部キーを追加することにより、postsテーブルにuser_id
が追加され、usersテーブルのid
とつながる。
##既存のマイグレーションを書き換えてみる!
はじめにpostsテーブルを作った時のマイグレーションを修正してみた。
class CreatePosts < ActiveRecord::Migration[6.0]
def change
create_table :posts do |t|
t.string :title
t.text :content
t.datetime :start_time
+ t.references :user, foreign_key: true
t.timestamps
end
end
end
何も起こらず、これではダメなよう...
##add_reference
でやってみる
上記にあったように新しくマイグレーションを作成する。
class AddUserToPosts < ActiveRecord::Migration[6.0]
def change
add_reference :posts, :user, foreign_key: true
end
end
ActiveRecord::Schema.define(version: 2021_02_17_101831) do
enable_extension "plpgsql"
create_table "posts", force: :cascade do |t|
t.string "title"
t.text "content"
t.datetime "start_time"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
+ t.bigint "user_id"
+ t.index ["user_id"], name: "index_posts_on_user_id"
end
create_table "users", force: :cascade do |t|
t.string "name"
t.string "email"
<!--some long code--!>
end
+ add_foreign_key "posts", "users"
end
+ t.bigint "user_id"
+ t.index ["user_id"], name: "index_posts_on_user_id"
+ add_foreign_key "posts", "users"
マイグレーションを行なうと上記の3行が追記され、user_id
も適応されている!
新たなマイグレーションでuser_id
が消えることもなくなった。