前回、Deviseを使用してユーザーのログイン機能を実装しました。
今回は、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モデルの関連付け(アソシエーション)が実装できました。