Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9359

Typormを使ってリレーションを組む

$
0
0
目標 userテーブルとtodoテーブルをつなげる どのユーザーがどんなタスクを持っているかを表示させる ユーザーにつき複数のタスクがつくようにする 目的 typeormのリレーションの組み方を学ぶ 1対多の紐付け方を学ぶ 手順 準備物・環境設定はこちら Typeormの設定のメモ typescriptでdoenvを使うときのメモ Typescriptとexpress.jsの環境設定 ルートを整える /users に対応するルートを別ファイルにする routesフォルダーを作りそこにusers.tsを作る // users.tsを以下のようにする import { Request, Response } from 'express' import { Router } from "express"; import { User } from '../entity/User' const router = Router(); // ユーザー詳細 router.get("/:id", async (req: Request, res: Response) => { const results = await User.findOneOrFail(req.params.id); return res.json(results); }); // 全ユーザーを表示 router.get("/", async (req: Request, res: Response) => { const results = await User.find(); return res.json(results); }); // ユーザーを登録 router.post("/", async (req: Request, res: Response) => { const user = await User.create(req.body); const results = await User.save(user); return res.json(results); }); // ユーザー情報を更新 router.put("/:id", async (req: Request, res: Response) => { // User.findOne()を使用するとエラーになるのでFindOneOrFailを使用 const user = await User.findOneOrFail(req.params.id); User.merge(user, req.body); const results = await User.save(user); return res.json(results); }); // ユーザーを削除 router.delete("/:id", async (req: Request, res: Response) => { await User.delete(req.params.id); const message = "The user is deleted!!" return res.json(message); }); export default router; //index.txを以下のように変更 import express, { Request, Response, NextFunction } from 'express' import todoRoutes from './routes/todos' import userRoutes from './routes/users' import "reflect-metadata"; import { createConnection } from "typeorm"; // create typeorm connection createConnection() .then(() => { // create and setup express app const app = express() app.use(express.json()); // register routes app.use('/todos', todoRoutes) app.use('/users', userRoutes) app.use((err: Error, req: Request, res: Response, next: NextFunction) => { res.status(500).json({ message: err.message }) }) // start express server app.listen(3000, () => console.log('Server up at http://localhost:3000')) }).catch(error => console.log(error)); todoテーブルを作る entityフォルダ内にTodo.tsをつくる // entity/Todo.ts import { BaseEntity, Entity, Column, PrimaryGeneratedColumn, CreateDateColumn, UpdateDateColumn } from "typeorm"; @Entity() export class Todo extends BaseEntity { @PrimaryGeneratedColumn() readonly id?: number; @Column({ type: 'varchar' }) title: string; @Column("text") description: string; @Column() isDone: boolean = false; @CreateDateColumn() readonly createdAt?: Date; @UpdateDateColumn() readonly updatedAt?: Date; // コンストラクタで初期化 constructor(title: string, description: string) { super(); this.title = title; this.description = description; } } 次にUser.tsを共通するところがあるのでまとめていきます。 entity内でModel.tsを作る // Model.ts import { BaseEntity, Entity, Column, PrimaryGeneratedColumn, CreateDateColumn, UpdateDateColumn } from "typeorm"; @Entity() export default abstract class Model extends BaseEntity { @PrimaryGeneratedColumn() readonly id?: number; @CreateDateColumn() readonly createdAt?: Date; @UpdateDateColumn() readonly updatedAt?: Date; // コンストラクタで初期化 constructor(model?: Partial<any>) { super(); Object.assign(this, model) } } User.tsとTodo.tsを変更する // User.ts import { Entity, Column, PrimaryGeneratedColumn } from "typeorm"; import Model from "./Model"; @Entity() export class User extends Model { @PrimaryGeneratedColumn() readonly id?: number; @Column({ type: 'varchar' }) name: string; @Column({ type: 'varchar' }) email: string; // コンストラクタで初期化 constructor(name: string, email: string) { super(); this.name = name; this.email = email; } } // Todo.ts import { Entity, Column } from "typeorm"; import Model from "./Model" @Entity() export class Todo extends Model { @Column({ type: 'varchar' }) title: string; @Column("text") description: string; @Column() isDone: boolean = false; // コンストラクタで初期化 constructor(title: string, description: string) { super(); this.title = title; this.description = description; } } todos.tsの処理を整えてCRUDができるようにする // todos.tsを以下のように変更する import { Request, Response } from 'express' import { Router } from "express"; import { Todo } from '../entity/Todo' const router = Router(); // ユーザー詳細 router.get("/:id", async (req: Request, res: Response) => { const results = await Todo.findOneOrFail(req.params.id); return res.json(results); }); // 全ユーザーを表示 router.get("/", async (req: Request, res: Response) => { const results = await Todo.find(); return res.json(results); }); // ユーザーを登録 router.post("/", async (req: Request, res: Response) => { const todo = await Todo.create(req.body); const results = await Todo.save(todo); return res.json(results); }); // ユーザー情報を更新 router.put("/:id", async (req: Request, res: Response) => { // Todo.findOne()を使用するとエラーになるのでFindOneOrFailを使用 const todo = await Todo.findOneOrFail(req.params.id); Todo.merge(todo, req.body); const results = await Todo.save(todo); return res.json(results); }); // ユーザーを削除 router.delete("/:id", async (req: Request, res: Response) => { await Todo.delete(req.params.id); const message = "The todo is deleted!!" return res.json(message); }); export default router; リレーションを組む userIdカラムをtodoテーブルの加えるためにTodo.tsに次のコードを加える。 Many to oneの考え方です。 //Todo.ts import { Entity, Column, ManyToOne, JoinColumn } from "typeorm"; import Model from "./Model" import { User } from "./User" // 追加 @Entity() export class Todo extends Model { @Column({ type: 'varchar' }) title: string; @Column("text") description: string; @Column() isDone: boolean = false; //----- 追加 @Column() userId!: number; @ManyToOne(() => User, user => user.todos) user!: User; //----- // userIdの初期化を追加 constructor(title: string, description: string, userId: number) { super(); this.title = title; this.description = description; this.userId = userId; } } User.tsにもTodo.tsと関係があることをコードを追加して表す。 こちらはone to manyの関係 import { Entity, Column, PrimaryGeneratedColumn, OneToMany } from "typeorm"; import Model from "./Model"; import { Todo } from "./Todo"; @Entity() export class User extends Model { @PrimaryGeneratedColumn() readonly id?: number; @Column({ type: 'varchar' }) name: string; @Column({ type: 'varchar' }) email: string; //----- 追加 @OneToMany(() => Todo, todo => todo.user) todos?: Todo[]; //----- // コンストラクタで初期化 constructor(name: string, email: string) { super(); this.name = name; this.email = email; } } 参考 TypeORM - Amazing ORM for TypeScript and JavaScript (ES7, ES6, ES5). Supports MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, WebSQL databases. Works in NodeJS, Browser, Ionic, Cordova and Electron platforms. TypeORM Tutorial (Seamless Typescript ORM)

Viewing all articles
Browse latest Browse all 9359

Trending Articles