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)写法关联逻辑本身没有问题,但有两个缺陷:
- 是内连接而非左连接,会自动过滤掉没有关联Certification的Project,和原Squeel的左连接逻辑不一致
- 排序字段没有指定表名,
parent_vendor_id和name都属于vendors表,直接写字段名会触发歧义报错
另外你贴出的Certification表schema中没有donaldson字段,建议确认数据库中该字段确实存在,避免后续运行报错。
内容的提问来源于stack exchange,提问作者Scott Milella
相关产品推荐
相关产品推荐

