回到项目,打开 PostService, 等会儿在这个服务里会用到 TagRepository ,所以需要把它作为这个服务类的依赖注入进来。
在类的构造方法里面, @InjectRepository 注入 Tag,private readonly 属性的名字叫 tagRepository,类型是 Repository,Tag。
再打开 Post 模块,在导入这里,TypeOrmModule,foreFeature 方法里,再添加一个 Tag。
在 PostService 服务里,先找到处理存储 Post 内容用的方法,就是这个 store 方法,它的 data 参数的值就是请求里带的主体数据,现在这个数据里面多了一个 tags 属性。
打开 PostDto,在里面添加一个新的属性,名字是 tags,它的值是一组 Tag[] ,注意这个 tags 属性没有标记成一个 readonly 属性。
回到 PostService ,在 store 方法里面,先从 data 参数里面,去把 tags 解构出来。
然后做一下判断,如果 data 参数里面包含 tags 属性,可以重新设置一下这个属性的值,这个动作可以交给一个方法去处理,名字叫 beforeTag,把 tags 交给这个方法,它的作用就是返回一组 Tag 实体。
找个地方去定义这个方法,方法的名字是 beforeTag,方法接收一个 tags 参数,类型是一组 Partial Tag。
方法里面添加一个 _tags,它的值用一下 tags 数组上的 map 方法,给它提供一个 async 回调,当前项目可以叫 item。
然后先从 item 里面去把 id,还有 name 解构出来。
再做一下判断,如果提供的标签项目里面有 id 属性, 可以先添加一个 _tag,它的值是 await,用一下 this.tagRepository 上的 findOne ,把标签的 id 交给它。
意思就是根据 tagId 的值找到对应的 Tag,如果找到了这个标签,我们就 return 这个标签,没找到的话可以直接 return。
下面还得再判断一下,如果提供的要给内容打的标签项目里面有 name 属性的值,可以先确定一下这个标签是不是存在,添加一个 _tag,await,this.tagRepository,findOne,根据标签的名字查询标签。
如果找到了这个标签,就 return 它。
要是按标签名字没找到对应的标签,我们就去创建一个标签,return 的是 await,this.tagRepository.save,保存 item。
最后让 beforeTag 方法 return 的数据应该是等待所有 Promise 都处理之后结果,用 Promise.all,把 _tags 交给这个方法。
测试
下面去测试一下 ,打开 HTTP 客户端, 发送一下之前我们配置好的这个创建内容的请求,请求里带的数据包含了 tags 属性,里面有两个项目,第一个项目里面提供了已经存在的标签的 id 号,第二个项目里提供了可能还不存在的标签的名字。
请求成功,回到数据库客户端检查一下,先打开 tag 这个表,这里会出现一个新的标签数据记录,它的 name 是 水。
然后打开 post_tags_tag,这里存储了内容与标签的关系,这个 id 号是 37 的 post 就是刚才我们发布的新内容的 id 号。
后面的 tagId 是给这个内容打上的标签的 id 号。
我们给这个内容打上了两个标签,所以在这个表里会存在两条数据记录,分别存储了这个内容与标签的关系。