Rails中Where/Join/Union用法问题:ActiveRecord查询失效求助
解决ActiveRecord查询失效投标与合并结果集的问题
嘿,我来帮你搞定这个查询问题~你遇到的核心问题是失效投标的查询没有正确关联Trip表,以及expired方法返回了错误的模型类型,咱们一步步来修复:
1. 修复Bid的expired Scope
你原来的expired方法直接返回了Trip对象,这显然不是你要的Bid。咱们需要从Bid出发,关联它所属的Trip,然后筛选出行程已过期的Bid:
class Bid < ApplicationRecord belongs_to :trip belongs_to :guide # 用scope定义,更符合Rails规范 scope :expired, -> { joins(:trip) # 关联Trip表,这样才能访问trips的字段 .where("trips.start_date < ?", Date.today) } end
2. 正确查询失效投标
现在在控制器里,你可以直接调用这个scope,结合guide_id筛选:
class GuidesController < ApplicationController def expired_declined # 已拒绝的投标查询保持不变(工作正常) @declined_bids = LosingBid.where(guide_id: current_guide.id) # 修复后的失效投标查询:返回Bid对象,且能正确筛选过期行程 @expired_bids = Bid.where(guide_id: current_guide.id).expired end end
小提示:不用把
current_guide.id转成字符串,ActiveRecord会自动处理类型匹配,这样更安全也更简洁。
3. 合并两个结果集(可选)
如果你想要一个统一的结果集,因为Bid和LosingBid是不同的模型,我们可以先选择两者共有的字段,再合并成数组:
def expired_declined # 选择需要的字段(根据你的业务需求调整) expired_bids = Bid.where(guide_id: current_guide.id) .expired .select(:id, :trip_id, :guide_id, :created_at, :status) declined_bids = LosingBid.where(guide_id: current_guide.id) .select(:id, :trip_id, :guide_id, :created_at) # 合并并按创建时间排序(可选) @combined_bids = (expired_bids + declined_bids).sort_by(&:created_at).reverse end
为什么之前的代码会报错?
- 第一个
@expired_bids返回Trip:因为你的expired方法里写的是Trip.where(...),直接返回了Trip模型的集合,而不是Bid。 - 第二个
@expired_bids报错:因为你在Bid的查询里直接用了trips.start_date,但没有通过joins(:trip)关联Trip表,SQL语句里没有JOIN,自然找不到trips.start_date这个字段。
这样调整后,你就能正确获取到两类投标啦~
内容的提问来源于stack exchange,提问作者Mike N.
相关产品推荐
相关产品推荐

