yuuto222
@yuuto222 (hayasaki yuuto)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

自転車一覧画面に自転車の使用履歴にある最新の返却日時のみを表示させたい。

Q&A

Closed

解決したいこと

自転車一覧画面に自転車の使用履歴にある最新の返却日時のみを表示させたい。

概要
Docker環境上でRuby on railsを用いて、自転車のレンタル機能を開発しております。
自転車一覧画面と自転車使用履歴画面があり、1(自転車一覧画面)対多(自転車の使用履歴の画面)で関連付けしております。

db/schema.rb

create_table "bicycle_logs", comment: "自転車使用履歴", force: :cascade do |t|
    t.bigint "bicycle_id", comment: "自転車id"
    t.datetime "take_datetime", comment: "持ち出し日時"
    t.bigint "take_user_id", comment: "持ち出し日時"
    t.datetime "return_datetime", comment: "返却日時"
    t.bigint "return_user_id", comment: "返却日時"
    t.integer "before_weight", comment: "使用前重量"
    t.integer "after_weight", comment: "使用後重量"
    t.integer "used_weight", comment: "使用量"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["bicycle_id"], name: "index_paintcan_logs_on_paintcan_id"
  end
create_table "bicycles", comment: "自転車", force: :cascade do |t|
    t.datetime "arrival_datetime", comment: "入荷日時"
    t.string "product_number", comment: "品番"
    t.integer "weight", comment: "重量"
    t.bigint "location_id", comment: "ロケーションid"
    t.bigint "create_user_id", comment: "作成者id"
    t.bigint "update_user_id", comment: "更新者id"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

発生している問題・エラー

自転車使用履歴画面には自転車一台に対して、持ち出し日時と返却日時があり、持ち出しと返却を行った回数分のデータが存在します。そのため、自転車一覧画面に返却日時を表示させようとした場合、複数のデータが表示されてしまう。
*更新日時に返却日時を代入している
スクリーンショット 2023-01-08 14.07.36.png

該当のソースコード

app/views/bicycles/index.html.slim

= render_with_pagination(bicycles) do |bicycles|
    .table-sticky.max-vh-70
      table.table.table-sm.table-bordered.table-striped.table-hover.text-nowrap
        thead
          tr
						省略
            th= sort_link_to :updated_at
              |更新日時
            省略

        tbody
          - bicycles.each do |bicycle|
            tr
						省略
              - bicycle.bicycle_logs.each do |bicycle_log|
                td=  bicycle_log.return_datetime
						省略

app/models/bicycle.rb

has_many :bicycle_logs, dependent: :restrict_with_error

app/models/bicycle_log.rb

belongs_to :bicycle, optional: false

自分で試したこと

モデルにメソッドを定義し、VIEWに表示させました。以下のコメントアウトした様々な方法で返却日時であるreturn_datetimeを表示させた上で最新のデータのみを表示させようとしましたが、上手く行かず、何か思いつく方法があれば、教えて頂けると幸いです。
app/models/bicycle_log.rb

def a
    bicycle_logs = BicycleLog
      # .search(params)
      # .order_by(params[:sort])
      # .find(&:return_datetime).last
      # .find(params[:return_datetime])
      # .find(&:return_datetime)
      # .where(&:return_datetime)
      # .pluck(:return_datetime)
      # .order(return_datetime: :desc)
      # .find{(_1.return_datetime) <= date.max}
  end

app/views/bicycles/index.html.slim

= render_with_pagination(bicycles) do |bicycles|
    .table-sticky.max-vh-70
      table.table.table-sm.table-bordered.table-striped.table-hover.text-nowrap
        thead
          tr
						省略
            th= sort_link_to :updated_at
              |更新日時
            省略

        tbody
          - bicycles.each do |bicycle|
            tr
						省略
              - bicycle.bicycle_logs.each do |bicycle_log|
                td=  bicycle_log.a
						省略

補足情報(FW/ツールのバージョンなど)

バージョン情報
Rails 6.1.4.7
ruby 3.1.2
Docker 20.10.11

0

1Answer

試してないのであれですが、現在のデータ構造のまま行くなら次のようにしてあげれば表示できるかと思います。

bicycle.rb
# N+1になるので注意
# レコードが多いとorderが遅くなるのでreturn_datetimeにindexつけたほうが良いかも
def recent_bicycle_log
  self.bicycle_logs.order(return_datetime: :desc).first 
end
index.html.slim
省略
tbody
- bicycles.each do |bicycle|
  tr
  省略
  - bicycle.recent_bicycle_log&.return_datetime
省略
1Like

Comments

  1. @yuuto222

    Questioner

    おかげで解決することができました!詰まっていたので、本当に助かりました!ありがとうございます!

Your answer might help someone💌