BlogモデルとUserモデルの関連付け(アソシエーション)

前回、Deviseを使用してユーザーのログイン機能を実装しました。

maa0917.hatenablog.com

今回は、BlogモデルとUserモデルを関連付けを実装します。

  • BlogモデルとUserモデル、一対多で関連付ける
  • Blogモデルは外部キーとしてuser_idを持つ
  • 投稿ユーザー名の表示

後付でBlogモデルに外部キーuser_idを設定

前回まででBlogモデル、Userモデルはすでに存在しているので、後付で外部キーを設定します。

$ rails g migration AddUserRefToBlogs user:references

次のようなマイグレーションファイルが作成されます。 (db:migrate/**************_add_user_ref_to_blogs.rb)

class AddUserRefToBlogs < ActiveRecord::Migration[5.2]
  def change
    add_reference :blogs, :user, foreign_key: true
  end
end

マイグレーションを実行します。

rails db:migrate

以下のようになります。

(db/schema.rb)

ActiveRecord::Schema.define(version: ****_**_**_******) do
  create_table "blogs", force: :cascade do |t|
# (省略)
    t.bigint "user_id"
    t.index ["user_id"], name: "index_blogs_on_user_id"
  end

# (省略)
class User < ApplicationRecord
  add_foreign_key "blogs", "users"
end

BlogモデルとUserモデル、一対多で関連付ける

アソシエーションを実装していきます。

(app/models/user.rb)

class User < ApplicationRecord
 # (省略)
  has_many :blogs
end

userは複数の投稿を持つので、blogsと複数形になります。

(app/models/blog.rb)

class Blog < ApplicationRecord
# (省略)
  belongs_to :user
end

blogは一人のユーザーに属するので、userは単数形になります。 これでblogとuserが1対多で関連付けられました。

createアクションを修正

新規投稿時にuser_idがcurrent_user.idがuser_idとなるようにcreateアクションを実装していきます。

(app/controllers/blogs_controller.rb)

  def create
    # @blog = Blog.new(blog_params)
    # @blog.user_id = current_user.id

    # 上の2行は下記の1行に書き換えることができる。習慣的にbuildを使う。
    @blog = current_user.blogs.build(blog_params)
   
    # (省略)
  end

これでblogを投稿するとcurrent_userと紐付けられたblogがdb に保存されます。

viewで投稿ユーザー名を表示

blogとuserが紐付いたので、blogに投稿ユーザー名を表示していきます。

(app/views/blogs/index.html.erb)

      <th>投稿者</th>
<!-- (省略) -->
      <td><%= blog.user.name %></td>

(app/views/blogs/show.html.erb)

<p>
  <strong>投稿者:</strong>
  <%= @blog.user.name %>
</p>

これでBlogモデルとUserモデルの関連付け(アソシエーション)が実装できました。