从 D10 开始往后会训练使用内容的关系。在应用里的内容与内容之间存在某种关系,比如用户与文章,文章与评论,用户与评论,分类与文章,标签与文章等等。我们需要根据关系的类型去定义这些内容与内容之间的关系,这样在创建内容的时候才能存储内容的关系,存储了内容的关系以后就可以利用内容的关系。
比如用户(User)是一种实体,文章(Post)也是应用里的一种实体。这两种实体之间存在某种关系,一个用户可以发布多个文章内容,就是可以关联多个文章内容,一个文章内容只能属于一个用户。对于用户实体来说,它跟内容是一对多(OnToMany)的关系,对于文章实体,它跟用户是多对一(ManyToOne)的关系。
在 Nest.js 应用里。在实体的定义里可以描述内容之间的这个关系,下面是在 User 实体里面,描述他跟 Post 实体的关系:
src/modules/user/user.entity.ts
@Entity() export class User { @PrimaryGeneratedColumn() id: number; @Column('varchar', { unique: true }) name: string; @OneToMany(type => Post, post => post.user) posts: Post[]; }在@OneToMany
在 User 实体里,用 @OneToMany 装饰器定义了多对一的关系,这个关系的名字叫 posts,它的类型是一组 Post 实体。也就是访问这个 posts 关系,得到的应该就是一组文章内容。
给 @OneToMany 提供了两个回调,第一个回调描述了这个关系关联的实体类型(type)是 Post,第二个回调描述了在另外一边,也就是在 Post 实体那边对应的关系。post.user 意思就是在 Post 实体那里,应该有个 user 关系。
下面是在 Post 实体上描述的它跟 User 实体的关系:
src/modules/post/post.entity.ts
@Entity() export class Post { @PrimaryGeneratedColumn() id: number; @ManyToOne(type => User, user => user.posts) user: User; }
有了这个关系,再发布新文章内容的时候就可以存储一下它跟用户的关系:
async store(data: PostDto, user: User) { const entity = await this.postRepository.create(data); await this.postRepository.save({ ...entity, user }); return entity; }
在提取文章内容的时候,也可以包含需要的内容关系:
async index() { const entities = await this.postRepository.find({ relations: ['user'] }); return entities; }
上面这个方法会返回一组文章内容,每个文章内容里都会包含一个 user 属性,它的值就是这个文章内容的作者相关的信息。