Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
4
Help us understand the problem. What is going on with this article?
@soehina

【Rails】投稿とユーザーの紐付け(一対多)のメモ

More than 1 year has passed since last update.

経緯

現在ポートフォリオ用に「book memory phrase」というアプリを作っています。
自分が印象に残ったフレーズを引用した書籍とともに紹介して本との出会いを作る場です。

そこでユーザーと投稿の紐付けを行って、誰がどの投稿をしたか一覧で見れるような機能を実装したのですが、has_manyやbelongs_toなど学ぶことが多かったのでアウトプットしとこうと思います。

投稿したユーザーid

まずはデータベース上のidを紐付ける必要があります。

今回の場合だと、UserテーブルのidをPostテーブルに突っ込んで、誰の投稿かわかるようにします。

最初からこの機能は実装する気でいたので、Postテーブルを作る時点でidカラムとは別にuser_idカラムを作り、投稿する際にユーザーのidを突っ込めるようにしてました。

その辺については以前書いた【Rails】railsブログサイトの練習で躓いたところメモにも載せていますのでそちらを参考にしてもらえたらと思います。

Modelの設定

idが突っ込めたら次は紐付けです。これはModelで設定します。

has_many

has_manyは一対多の多の方です。
ユーザー1に対して投稿は多数あるので、ユーザーモデルにhas_manyを記述します。

user.rb
has_many :posts, dependent: :destroy, foreign_key: :post_user_id

投稿は複数あるので複数系にしてください。

ちなみにdependent: :destroyはユーザーが削除されたら自動的に投稿も削除されるという優秀な機能です。

belongs_to

次は一対多の一の方、ユーザーの紐付けです。

post.rb
belongs_to:user

def user
   return User.find_by(id: self.user_id)
end

一の方はbelongs_toで紐付けられます。
また、userメソッドをモデルで定義しておけば汎用性が高くなるので書いときます。

Controllerの設定

私はuser_showというページで該当ユーザーの投稿一覧を表示したかったので、コントローラーに以下のように記述しました。

home_controller.rb
before_action :set_post, only[:user_show, :edit, :update, :destroy]

#省略

#@userにモデルで定義したuserメソッドを@post.userで代入
#@postsに@userの投稿を全て代入
def user_show
   @user = @post.user
   @posts = @user.posts
end

#省略

private
#Post.find_by(id: params[:id])はよく使うので定義しといてbefore_actionで反映。
def set_post
   @post = Post.find_by(id: params[:id])
end

これでコントローラーの準備は整いました。

Viewの設定

コントローラーで作った@postsをeach文で回してあげれば一覧が確認できます。

user_show.html.erb
<% @posts.each do |post| %>
   <div class="book-img col-lg-4 col-md-6 col-sm-12 center-block mx-auto">
      <div class="box">
         <div class="image-box">
            <h5><%= post.phrase %></h5>
            <p class="name">
               <span>投稿者&ensp;&ensp;</span><%= link_to("#{post.post_user}", "/home/#{post.id}/user_show")%>
            </p>
            <img src='<%= post.book_image %>' class="img-fluid d-block">
         </div>
         <div>
            <p class="title"><%= post.title %></p>
            <p class="author">
               著者 <%= post.author %>
            </p>
            <p>★ おすすめポイント</p>
            <p class="content">
               <%= post.content%>
               <% if user_signed_in? && current_user.id == post.user_id %>
                  <span class="edit-delete">
                  <%=link_to("編集" , "/home/#{post.id}/edit",class:"text-muted") %>
                  <%=link_to("削除" , "/home/#{post.id}/destroy",method: :post,class:"text-muted") %>
                  </span>
               <% end %>
            </p>
         </div>
      </div>
   </div>
<% end %>

まとめ

投稿の紐付けは必須機能ですが、結構躓くところでもあると思います。

かく言う私も何度も躓いたのですがSQLを勉強したら結構スッと入ってこれました。
イメージって大事ですね。

もしこの記事が誰かの助けになれたら幸いです。
ではでは。

4
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
soehina
ruby on rails を中心にアプリ開発を学んでいます。 フロントに興味があるのでJavascriptとReactも勉強中。 現在は大阪にてSESをしており、たまにWebライティングもしております。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
4
Help us understand the problem. What is going on with this article?