高瀬博道の技術ブログ

高瀬博道の技術ブログです。

TypeORMに入門する - 10

前回

takasehiromichiex.com

関係の逆側

PhotoMetadataからPhotoへのリレーションは貼れていますが、Photoから PhotoMetadataへのリレーションは貼れていません。

リレーションを双方向にするためにエンティティを変更しましょう。

src/entity/Photo.ts
import { Column, Entity, OneToOne, PrimaryGeneratedColumn } from "typeorm";
import { PhotoMetadata } from "./PhotoMetadata";

@Entity()
export class Photo {
  @PrimaryGeneratedColumn()
  id: number;
  @Column({ length: 100 })
  name: string;
  @Column("text")
  description: string;
  @Column()
  filename: string;
  @Column("double")
  views: number;
  @Column()
  isPublished: boolean;
  @OneToOne(() => PhotoMetadata, (photoMetadta) => photoMetadta.photo)
  metadata: PhotoMetadata;
}
src/entity/PhotoMetadata.ts
import {
  Column,
  Entity,
  JoinColumn,
  OneToOne,
  PrimaryGeneratedColumn,
} from "typeorm";
import { Photo } from "./Photo";

@Entity()
export class PhotoMetadata {
  @PrimaryGeneratedColumn()
  id: number;
  @Column("int")
  height: number;
  @Column("int")
  width: number;
  @Column()
  oriientation: string;
  @Column()
  compressed: boolean;
  @Column()
  comment: string;
  @OneToOne(() => Photo, (photo) => photo.metadata)
  @JoinColumn()
  photo: Photo;
}

@OneToOne(() => PhotoMetadata, (photoMetadta) => photoMetadta.photo)@OneToOne(() => Photo, (photo) => photo.metadata)に変更しています。

一方で、@JoinColumn()デコレータは、所有される側にのみ設置します。

実行すると、以下のようになります。

+----+--------+-------+--------------+------------+---------------+---------+
| id | height | width | oriientation | compressed | comment       | photoId |
+----+--------+-------+--------------+------------+---------------+---------+
|  1 |    777 |   555 | portrait     |          1 | my comment... |       4 |
|  2 |    777 |   555 | portrait     |          1 | my comment... |       5 |
+----+--------+-------+--------------+------------+---------------+---------+
2 rows in set (0.03 sec)

mysql> select * from photo;
+----+-----------------+-------------------+------------------+-------+-------------+
| id | name            | description       | filename         | views | isPublished |
+----+-----------------+-------------------+------------------+-------+-------------+
|  2 | my photo        | my description    | photo.jpg        |     1 |           1 |
|  3 | my photo        | my description    | photo.jpg        |     1 |           1 |
|  4 | my new photo... | my description... | my photo name... |     0 |           1 |
|  5 | my new photo... | my description... | my photo name... |     0 |           1 |
+----+-----------------+-------------------+------------------+-------+-------------+
4 rows in set (0.00 sec)

カラムの追加は、@JoinColumn()デコレータ側にのみ行われます。

ESMの使用

TypeScriptでESMを使用する場合は、循環依存が発生するので、ラッパータイプを使用する必要があるようです。

photo: Relation<Photo>
...
metadata: Relation<PhotoMetadata>

まとめ

ここまでで、

  • 関係の逆側について
  • ESMの使用について

を学びました。

次回はオブジェクトとそのリレーションのロードについて掘り下げようと思います。

コード

今回のコードは、以下に格納しました。

github.com

takasehiromichiex.com