You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails电影租赁应用:实现影片及可用库存数量统计展示

解决Rails电影租赁应用中重复显示影片及统计可用库存的问题

我来帮你搞定这个问题!你现在遇到的核心问题是遍历库存记录导致同一部影片重复渲染——因为每一条库存记录都关联着同一个影片,自然会重复输出。我们需要调整查询逻辑,直接从Film模型入手,同时统计每部影片的可用库存数量,这样就能实现每部影片只显示一次的需求。

问题根源拆解

你当前的控制器取了所有Inventory记录,然后在视图里遍历每个库存、输出对应的影片信息。由于同一部影片对应多条库存记录(比如你示例里film_id=1有2条可用库存),所以同一部影片会被重复渲染多次,这就是问题所在。

最优解决方案:一次性查询影片+统计可用库存

我们可以用ActiveRecord的查询语句,一次性获取所有影片并同步统计每部的可用库存数,既避免N+1查询,也能解决重复显示的问题。

1. 修改Inventory控制器的index动作

把原来获取所有库存的逻辑,改成查询影片并统计可用库存:

def index
  # 查询所有影片,同时统计每部影片的可用库存数(包含库存为0的影片)
  @films = Film.left_joins(:inventories)
               .group('films.id')
               .select(
                 'films.*',
                 "COUNT(CASE WHEN inventories.checkout_status = 'available' THEN inventories.inventory_id END) AS available_inventory_count"
               )
end
  • left_joins(:inventories):左连接影片和库存表,确保哪怕没有库存的影片也能被查询到
  • group('films.id'):按影片ID分组,保证每部影片只返回一条记录
  • 带CASE的COUNT语句:只统计checkout_status为available的库存数量,没有可用库存的影片会显示0

2. 更新视图代码

现在视图需要遍历@films而非@inventory,输出每部影片的信息和可用库存数:

<% @films.each do |film| %>
  <div class="film-card">
    <h2><%= film.title %></h2>
    <p><%= film.description %></p>
    <p><strong>可用库存:</strong><%= film.available_inventory_count %></p>
  </div>
<% end %>

备选方案:在Film模型中封装统计逻辑(注意性能)

如果你更习惯把业务逻辑放在模型层,可以在Film模型里添加一个方法计算可用库存,但要注意避免N+1查询:

# app/models/film.rb
class Film < ApplicationRecord
  has_many :inventories

  def available_inventory_count
    inventories.where(checkout_status: 'available').count
  end
end

然后控制器里要预加载库存来优化性能:

def index
  @films = Film.includes(:inventories).all
end

视图代码和上面一致,调用film.available_inventory_count即可。不过这种方式在影片数量较多时,性能不如第一种一次性查询的方案,因为每部影片都会单独执行一次count查询。

验证效果

现在重启你的应用,就能看到每部影片只显示一次,并且正确对应可用库存数量了(比如你示例里的film_id=1会显示可用库存:2)。

内容的提问来源于stack exchange,提问作者pbybel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:32:09