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

如何通过原生SQL查询获取用户(Profile)的Avatar URL?

在Rails原生SQL中关联Active Storage获取头像完整URL

要在原生SQL中获取头像的完整URL,你需要关联Active Storage的两个核心表:active_storage_attachments(记录附件与模型的关联关系)和active_storage_blobs(存储附件元数据,包括文件唯一标识key)。

修改后的原生SQL查询

使用LEFT JOIN确保即使没有上传头像的用户也能被正常返回:

SELECT 
  u.id as user_id,
  p.name,
  ab.key as avatar_key,
  ab.filename as avatar_filename
FROM 
  users as u
JOIN 
  profiles as p ON u.id = p.user_id
LEFT JOIN 
  active_storage_attachments asa 
  ON asa.record_id = p.id 
  AND asa.record_type = 'Profile' 
  AND asa.name = 'avatar'
LEFT JOIN 
  active_storage_blobs ab ON asa.blob_id = ab.id
WHERE u.department_id = 1

生成完整头像URL

直接在SQL中拼接URL不够灵活(不同存储服务如本地磁盘、S3的URL结构存在差异),推荐在Ruby层面用Rails内置方法生成标准URL:

users = User.find_by_sql(sql)
result = users.map do |user|
  {
    user_id: user.user_id,
    name: user.name,
    avatar_url: user.avatar_key ? Rails.application.routes.url_helpers.rails_blob_url(user.avatar_key, only_path: false) : nil
  }
end.to_json

关键关联逻辑说明

  1. active_storage_attachments通过三个条件与profiles表关联:record_id对应profile的ID、record_type固定为模型名Profile、name对应附件字段名avatar
  2. active_storage_blobs通过blob_id与active_storage_attachments关联,获取文件的唯一key
  3. 使用LEFT JOIN而非JOIN,避免过滤掉未上传头像的用户记录

替代方案(Rails关联查询)

如果不想写原生SQL,也可以用Rails的查询接口实现相同效果,更符合框架风格:

users = User.joins(:profile)
            .left_joins(profile: { avatar_attachment: :blob })
            .where(department_id: 1)
            .select(
              'users.id as user_id',
              'profiles.name',
              'active_storage_blobs.key as avatar_key'
            )

result = users.map do |user|
  {
    user_id: user.user_id,
    name: user.name,
    avatar_url: user.avatar_key ? Rails.application.routes.url_helpers.rails_blob_url(user.avatar_key, only_path: false) : nil
  }
end.to_json

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 13:20:30