Creating a Reddit Clone Using React and GraphQL - 13
Tags: react, typescript, graphql, redditclone
Published: 2021-03-20 13:16:56

### This blog post originally posted on my blog site and you can find it [here](https://www.rasikag.com/posts/creating-a-reddit-clone-using-react-and-graphql-13).

Now we want to add the relationship with `POST` and `USER`. This is a one-to-many relationship. In the MikrORM documentation, the many-to-one relationship can create by adding `@ManyToOne` in the entity. In example,

```javascript

// mikro orm documentation example
@Entity()
export class Book {

@ManyToOne()
author!: Author;

}

```

But when we set the value of `author` to `Book` entity, we need to manually get the `author` and set it. If we searched more, we can set the `author` like this,

```javascript
// mikro orm documentation exaple
book.auther = orm.em.getReference < Author > (Author, "...id...");
```

So, because of that, we are moving to `TypeORM.` Yeah, kinda huge change.

To add TypeORM to the server project, use this yarn command.

```javascript

yarn add typeorm

```

Then we need to change the `index.ts` file in the server project. First we need to add the config object to `TypeORM`. I created a new database for `typeorm`.

```javascript
const conn = await createConnection({
  type: "postgresql",
  database: "redditdev03",
  username: "postgresql",
  password: mySecretKeys.myDbPassword,
  logging: true,
  synchronize: true,
  entities: [],
});
```

In the above code, I need to add entities. Before that, we need to change our current entities to match with `typeorm`.

I change the `User` and `Post` Files. We need to change Property to Column and there are other annotations related to `type-orm` and replace with `mikro-orm` annotation. I will mention new annotations here and you can check the full changed file in GitHub.

```javascript
PrimaryGeneratedColumn, CreateDateColumn, UpdateDateColumn, Column;
```

Now we can fill `entities` array from `type-orm`config object. We can remove `mikro-orm` related things from `index.ts` file. Also we don’t need to pass anything to context object. Now our `ApolloServer` context object like this.

```javascript

context: ({ req, res }: RedditDbContext) => ({
  res,
  redis,
}

```

We can extend `BaseEntity` in `User` and `Post` entity classes. Because of that, we can use pre-defined methods for data manipulation. In the `RedditDbContext` object form `types.ts` file, we don’t need `mikro-orm` object. We can remove it. We used that `mikro-orm` object to access context in our resolvers. Let’s go and fix those. Because we extended the `BaseEntity` type from `User` and `Post` entities, we can use those methods in resolvers like `Post.find()`.

For reference here is the insert query.

```javascript
return Post.create({ title }).save();
```

So, now we just change the `post` resolver and `user` resolver. (There are so many small changes to match with `type-orm` each method. So please refer to the Github files.)

If we try to find something without a primary key we need to use `where` property in `findOne` method.

```javascript
await User.findOne({ where: { email } });
```

While moving to `type-orm` we can use its query builder. Here is the code for that.

```javascript
const result = await getConnection()
  .createQueryBuilder()
  .insert()
  .into(User)
  .values({
    username: options.username,
    email: options.email,
    password: hashedPassword,
  })
  .returning("*")
  .execute();
```

Now we all set the `type-orm`. Let’s add the relationship to `Post` entity.

```javascript

@Field()
@Column()
creatorId: number;
// posts need to match with User's property name
@ManyToOne(() => User, user => user.posts)
creator: User;

```

So we need to add the `posts` property in the `User` entity.

```javascript

@OneToMany(() => Post, (post) => post.creator)
posts: Post[];

```

Also, we are adding new fields to `Post` entity. Because these are not null fields, we need to clear `Post` table and start it again.

```javascript

@Field()
@Column()
text!: string;

@Field()
@Column({type: "int", default: 0})
points!: number;

```

Then we are creating a `InputType` for the post. This will easier to work with the front-end.

```javascript
@InputType()
class PostInput {
  @Field()
  title: string;
  @Field()
  text: string;
}
```

Then we need to change the `createPost` method in `post` resolver.

```javascript

@Mutation(() => Post)
async createPost(
  @Arg("input") input: PostInput,
  @Ctx() { req }: RedditDbContext
): Promise<Post> {
  return Post.create({ ...input, creatorId: req.session.userId }).save();
}

```

Now we have a slight error that event anyone can create a post without login to the system. We can avoid it by checking user id in the session, but any place that we need to check user logging status we need to add a `if` statement. To avoid that we can use middleware. Let’s see how can we use middleware from the next post.

---

Thanks for reading this. If you have anything to ask regarding this please leave a comment here. Also, I wrote this according to my understanding. So if any point is wrong, don’t hesitate to correct me. I really appreciate you.
That’s for today friends. See you soon. Thank you.

**References:**

This article series based on the [Ben Award - Fullstack React GraphQL TypeScript Tutorial](https://www.youtube.com/watch?v=I6ypD7qv3Z8). This is an amazing tutorial and I highly recommend you to check that out.

Main image [credit](https://www.pexels.com/photo/green-pine-trees-covered-with-fogs-under-white-sky-during-daytime-167699/)