4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Rails/ActiveRecord】最新3件のみを取得。残りはプルダウンで表示する。を実装

Posted at

概要

  • コメント投稿機能を実装したい
  • コメントは全件表示したい
  • けど全部表示するのは邪魔だから、最新3件だけ表示して残りは必要なときだけ表示したい

<完成形イメージ>
decmo


環境

  • macOS Catalina 10.15.6
  • ruby 2.6.5
  • Rails 6.0.3.4

学んだこと

  • ActiveRecord
    • first : 引数に指定した数だけレコードを取得するメソッド
    • offset : 引数に指定した数だけレコードを読み飛ばすメソッド
  • HTML
    • details : 折りたたみウィジェット (クリックしたら開くオブジェクト) を生成するHTML要素
    • summary : detail要素のバーの文字を指定 (上のGIFでいう「全てのコメントを表示」)

今回のコード

  • 必要部分のみを抜粋します
  • association等は省略

1. itemsコントローラ

  1. items#show のリクエストを受け取る
  2. before_action :set_item で商品情報を取得
  3. before_action :set_comments で商品に紐づくコメントを全件取得 (新着順)
  4. 全コメントにfirst(3)適用 : 上から3件を取得
  5. 全コメントにoffset(3)適用 : 上から4件目以降を全取得
  6. 以上のデータをshow.html.erbに渡す
app/controllers/items_controller.rb

class ItemsController < ApplicationController
  before_action :set_item, only: [:show]
  before_action :set_comments, only: [:show]

  def show
    @comment = Comment.new
    # 新着コメントを上から3件取得
    @comments_latest3 = @item_comments.first(3)
    # 新着コメント3件を除く全コメントを取得 (3件以下の場合は空)
    @comments_offset3 = @item_comments.offset(3)
  end


  private

  def set_item
    # PATHパラメータでitemを取得
    @item = Item.find(params[:id])
  end

  def set_comments
    # itemに紐づくcommtnsを新着順で取得
    @item_comments = @item.comments.includes(:user).order('created_at DESC')
  end

end

2. show.html.erb

  1. 部分テンプレートで最新3件を表示
  2. 4件目以降がない場合はそのまま終了
  3. 4件目以降があった場合は、折りたたみウィジェットの中に4件目以降を全表示
app/views/items/show.html.erb

<%# コメント一覧を表示 %>
<div id="comment-lists">
  <%= render partial: 'shared/comment', collection: @comments_latest3 %>
  <%# コメントが4件未満の場合はここから表示しない %>
  <% if @comments_offset3.any? %>
    <details>
      <summary>全てのコメントを表示</summary>
      <%= render partial: 'shared/comment', collection: @comments_offset3 %>
    </details>
  <% end %>
</div>
app/views/shared/_comment.html.erb

<div class="comment-box">
  <div class="comment-info">
    <%# user名を表示 %>
    <p class="comment-user"><%= comment.user.nickname %></p>
    <%# 投稿時間を表示 %>
    <p class="comment-time"><%= l comment.created_at %></p>
  </div>
  <%# 改行が反映される形でコメントを表示 %>
  <p><%= simple_format(h(comment.text)) %></p>
</div>

その他、工夫したこと

  • コメントにユーザー情報を載せるときにN+1問題を回避したこと (includes メソッド)
  • コメント投稿時刻を日本時間にしたこと (l メソッド)
  • コメントに記入した改行が実際の表示に反映されるようにしたこと (simple_format)
  • simple_format 使用時に文字をエスケープさせたこと (h オプション)

参考

4
2
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
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?