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

Rails v3.2升级v6.1时重写Squeel DB查询关联报错求助

错误根源

你遇到的报错核心原因是joins(vendor: :certifications)的写法逻辑错误:该语法表示关联Vendor模型下名为certifications的关联,但根据你给出的模型定义,Vendor和Certification不存在直接关联,自然无法找到对应关联项报错。
原Squeel语句的joins{vendor}.joins{certifications.outer}是两次独立基于Project自身关联的查询:第一次关联Project所属的Vendor,第二次左连接Project下属的Certification,不属于嵌套关联逻辑,是你之前的写法理解错了关联层级。


适配方案

方案1:保持以Project为查询主体(完全对齐原Squeel逻辑)

Rails 5+ 已内置left_joins方法实现左连接,同时因为排序字段属于vendors表,需要显式指定表名避免字段歧义:

# 替换为实际传入的vendor_id变量
target_vendor_id = params[:vendor_id]

Project.joins(:vendor)
       .left_joins(:certifications)
       .where(
         "projects.vendor_id = :vid OR vendors.parent_vendor_id = :vid OR (certifications.donaldson = TRUE AND certifications.published = TRUE)",
         vid: target_vendor_id
       )
       .distinct
       .order("vendors.parent_vendor_id ASC, vendors.name ASC")

方案2:对齐你给出的Rails 3.2实际输出SQL,返回Vendor结果集

如果实际业务需要返回符合条件的Vendor列表,直接从Vendor侧发起查询更简洁,生成的SQL和你给出的旧版输出完全一致:

# 替换为实际传入的vendor_id变量
target_vendor_id = params[:vendor_id]

Vendor.joins(projects: :certifications)
      .where(
        "projects.vendor_id = :vid OR vendors.parent_vendor_id = :vid OR (certifications.donaldson = TRUE AND certifications.published = TRUE)",
        vid: target_vendor_id
      )
      .distinct
      .order(:parent_vendor_id, :name)

补充说明

你之前的joins(:vendor, :certifications)写法关联逻辑本身没有问题,但有两个缺陷:

  1. 是内连接而非左连接,会自动过滤掉没有关联Certification的Project,和原Squeel的左连接逻辑不一致
  2. 排序字段没有指定表名,parent_vendor_id和name都属于vendors表,直接写字段名会触发歧义报错
    另外你贴出的Certification表schema中没有donaldson字段,建议确认数据库中该字段确实存在,避免后续运行报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 11:39:01