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

如何将hasMany关联对象数组转为id数组,解决Ember读取Hasura关联数据问题

你遇到的问题是Ember Data默认不识别Hasura返回的嵌套对象数组格式的关联字段,优先选择在Ember侧通过序列化器适配,不需要修改Hasura侧的返回结构,避免破坏接口的通用性。

问题原因

Ember Data默认遵循JSON:API规范,关联数据默认要求放在relationships字段下,或显式配置嵌入式关联规则。你当前将photos对象数组直接放在movie的属性层级,Ember Data没有对应配置的话不会将其识别为hasMany关联,自然无法读取渲染。


方案1:Ember侧实现(推荐)

步骤1:定义正确的模型关联

首先保证movie和photo模型的关联声明正确:
app/models/movie.js

import Model, { attr, hasMany } from '@ember-data/model';

export default class MovieModel extends Model {
  @attr('string') movieid;
  @attr('string') description;
  // 因为数据是和movie一起返回的,async设为false不需要单独发起请求
  @hasMany('photo', { async: false }) photos;
}

app/models/photo.js

import Model, { belongsTo } from '@ember-data/model';

export default class PhotoModel extends Model {
  @belongsTo('movie') movie;
}

步骤2:配置序列化器适配嵌套结构

新增movie对应的序列化器,识别嵌入式的photos字段:
app/serializers/movie.js

import JSONSerializer from '@ember-data/serializer/json';

export default class MovieSerializer extends JSONSerializer {
  // 配置嵌入式关联规则,设为ids表示只提取关联资源的id,需要完整属性则设为'records'
  embeddedRecords = {
    photos: 'ids'
  };

  // 如果你需要直接把photos转成纯id数组存储,也可以重写normalize方法手动处理
  normalize(modelClass, resourceHash) {
    if (Array.isArray(resourceHash.photos)) {
      resourceHash.photos = resourceHash.photos.map(item => item.id);
    }
    return super.normalize(...arguments);
  }
}

如果你使用的是JSONAPISerializer,只需要调整normalize方法,把嵌套的photos数据移动到relationships字段下即可。


方案2:Hasura侧实现(不推荐)

如果非要在后端修改返回格式,你可以通过PostgreSQL自定义函数或Hasura聚合查询实现,示例查询写法如下:

query GetMovies {
  movies {
    id
    movieid
    description
    photo_ids: photos_aggregate {
      nodes {
        id
      }
    }
  }
}

但该方案会修改接口返回结构,其他端如果需要使用photos的其他属性时无法直接获取,因此不建议使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 07:45:06