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

Ruby on Rails:如何查询含至少1个分类14公司的城市

Rails 查询关联指定分类公司的城市实现方案

需求

获取所有满足以下条件的City记录:

  • 城市至少关联1家Company记录
  • 关联的Company的category_id为指定值(示例为14,也支持动态传入@category.id)

现有模型关联关系

三个模型均为多对多的has_and_belongs_to_many关联:

class City < ApplicationRecord
  has_and_belongs_to_many :categories   
  has_and_belongs_to_many :companies 
end

class Company < ApplicationRecord
  has_and_belongs_to_many :categories   
  has_and_belongs_to_many :cities 
end

class Category < ApplicationRecord
  has_and_belongs_to_many :companies   
  has_and_belongs_to_many :cities
end

原有写法问题

你当前写的查询存在两个明显问题:

# 错误代码
City.includes(:companies).where('companies.category_id' => @category.id)
  • 用includes做关联表条件查询时,未显式声明引用关联表,多数Rails版本会抛出找不到companies表的SQL错误
  • 未做去重处理:如果同一个城市下有多家符合分类要求的公司,查询结果会重复返回同一个城市记录

正确实现

场景1:仅需筛选城市,不需要后续访问关联的公司数据(性能最优)

直接用joins做内连接,天然过滤掉无匹配关联公司的城市,加distinct去重即可:

# 固定category_id为14的写法
City.joins(:companies).where(companies: { category_id: 14 }).distinct

# 动态传入分类id的写法
City.joins(:companies).where(companies: { category_id: @category.id }).distinct

说明:joins默认生成INNER JOIN语句,只会返回存在匹配关联公司的城市,完全满足「至少关联1家符合条件公司」的要求;用哈希形式的where条件companies: { category_id: xxx }比字符串写法更安全,不会出现SQL语法兼容问题。

场景2:查询后需要访问每个城市的关联公司列表(避免N+1查询)

如果后续逻辑需要遍历城市读取对应的公司数据,用includes搭配references,或者直接用eager_load预加载关联数据:

# 写法1:includes + references
City.includes(:companies)
    .where(companies: { category_id: @category.id })
    .references(:companies)
    .distinct

# 写法2:直接用eager_load
City.eager_load(:companies)
    .where(companies: { category_id: @category.id })
    .distinct

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 23:12:35