LoginSignup
2
5

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-02-11

経緯

現在ポートフォリオ用に「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を勉強したら結構スッと入ってこれました。
イメージって大事ですね。

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

2
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5