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

如何在ActiveRecord的Building模型中实现含楼层编号数组的查询方法

如何用ActiveRecord查询实现Building模型的some_stuff类方法?

我来帮你搞定这个需求!基于你现有的Building和Floor关联模型,下面分两种常用数据库场景,给出用ActiveRecord查询实现目标方法的方案:

方案一:适用于PostgreSQL数据库

PostgreSQL原生支持数组聚合函数,能直接生成我们需要的楼层number数组:

class Building < ActiveRecord::Base
  has_many :floors

  def self.some_stuff
    left_joins(:floors)
      .select(
        "buildings.id as id",
        "buildings.url as url",
        "array_agg(floors.number) as numbers"
      )
      .group("buildings.id, buildings.url")
      .map do |building|
        {
          id: building.id,
          url: building.url,
          numbers: building.numbers.compact # 移除无楼层时产生的nil值
        }
      end
  end
end

代码细节说明:

  • left_joins(:floors):确保即使没有关联楼层的建筑也能被查询到(如果只需要包含楼层的建筑,换成joins(:floors)即可)
  • array_agg(floors.number):把每个建筑对应的所有楼层number聚合为一个数组
  • group("buildings.id, buildings.url"):按建筑的唯一标识分组,保证每个建筑只返回一条结果
  • map方法:将ActiveRecord对象转换成你需要的哈希格式,compact处理无楼层时数组中的nil值

方案二:适用于MySQL数据库

MySQL没有原生数组类型,我们需要先用字符串拼接再转成数组:

class Building < ActiveRecord::Base
  has_many :floors

  def self.some_stuff
    left_joins(:floors)
      .select(
        "buildings.id as id",
        "buildings.url as url",
        "GROUP_CONCAT(floors.number SEPARATOR ',') as numbers"
      )
      .group("buildings.id, buildings.url")
      .map do |building|
        {
          id: building.id,
          url: building.url,
          numbers: building.numbers.present? ? building.numbers.split(',').map(&:to_i) : []
        }
      end
  end
end

代码细节说明:

  • GROUP_CONCAT(floors.number SEPARATOR ','):把楼层number用逗号拼接成字符串
  • split(',').map(&:to_i):将拼接后的字符串拆分成数组并转换为整数类型
  • present?判断:处理无楼层时返回空数组的情况

额外提示

如果你的Building模型id是UUID类型(和示例中的格式一致),要确保数据库中id字段已配置为UUID类型,否则查询会返回数据库存储的原生id格式(比如整数id)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:24:30