Sequelizejs関連


One-to-One
一対一のように見えますが、複数のペアがあります.ここでOne-To-Oneとは、照会データ(マスタテーブル)の結果であるべきです.関連情報は、単一の形でマスタテーブルの各オブジェクトに属性として掛けられています.
実際には、メインテーブルと関連表の複数対1の関係があります.
belongs To
SourceModel.belongsTo(TargetModel, { as, foreignKey, targetKey })
SourceModelのforeignKeyとTarget Modelの中のtarget Keyを関連付ける.asはTarget Modelの別名foreignKeyを配置し、SourceModelの外部キーフィールド名をデフォルトで${as || TargetModel.name}+${TargetModel.primaryKey}にTarget Modelのターゲットキーフィールド名を配置する.
検索した結果の構造は以下の通りです.
const sourceObj = {
  : ,
  : ,
  ...
  : targetObj
}
SourceModelにforeignKey関連Target Modelがあります.例えば、
Player.belongsTo(Team)
targetKeyは、SourceModelの外部キー名をカスタマイズするために使用されます.例えば、
User.belongsTo(Company, { foreignKey: 'cid' }) // User.cid    
デフォルトでは、foreignKey値はforeignKeyです.ここでの接続は、source modelの構成によって、camelCaseかundersscoredかが決定されます.例えば、
const User = this.sequelize.define('user', {}, { underscored: true })
const Company = this.sequelize.define('company', {
  uuid: { type: Sequelize.UUID, primaryKey: true }
})

User.belongsTo(Company) // User   foreignKey   company_uuid
${Team.name}+${Team.primaryKey}は、ターゲットModelにおいて、sourceModelの中外キーと一致するフィールド名を指定するために使用され、デフォルトはターゲットModelのprimryKeyである.
User.belongsTo(Company, { foreignKey: 'cid', targetKey: 'uuid' }) //    User.cid   Company.uuid     
targetKeyはターゲットModelのnameを変換するために用いられます.ここでは、foreignKeyを生成する際にターゲットModel nameを置換するという2つの態様があります.一つは、クエリの結果を綴り込む際に、ソールModelの属性の名前としてターゲットModelを変更します.例えば:
User.belongsTo(Company, { as: 'com' })

// foreign key would be: com_uuid
// company property of user object would be 'com'
has One
SourceModel.hasOne(TargetModel, { as, foreignKey })
SourceModelのプライマリキーとTarget Modelの外部キーを関連付けてas Target Modelを構成する別名asは、Target Modelの外部キーフィールド名を設定し、デフォルトはforeignKeyです.
クエリーの構造:
const sourceObj = {
  : ,
  : ,
  ...
  : targetObj
}
Target ModelにforeignKey関連SourceModelがあります.例えば、
Company.hasOne(User)
${as || SourceModel.name}+${SourceModel.primaryKey}はデフォルトforeignKeyであり、カスタムであってもよい.
Company.hasOne(User, { foreignKey: 'company_id' }) // User.company_id    
${Company.name}+${Company.primaryKey} hasOneにはtargetKey属性がありません.
belongs To V.S has One
関連情報(例えば、外部キー)がsourceに保存されている場合は、targetKey;関連情報がtargetに保存されている場合は、belongsToたとえば:
  • Playerテーブル、teamId関連Teamテーブル
  • Coachテーブル
  • Teamテーブル、coachId関連Coachテーブル
  • Player.belongsTo(Team) // Player.teamId -- Team.id
    Coach.hasOne(Team) // Team.coachId -- Coach.id
    どうして逆にできないですか?例えばhasOneでsourceとtargetを交換したら、Player.belongsTo(Team)を適用できますよね?問題はsourceは検索要求によって決められています.もしPlayerを調べて関連チーム情報を持ち出したら、sourceはPlayerだけです.
    小結:メインテーブル、つまりsourceによって、検索する関連表を見つけて、もし関連情報(外部キー)がsourceにあるならば、belongsTo、さもなければhasOne.
    One-to-Many
    has Many
    SourceModel.hasMany(TargetModel, { as, foreignKey, sourceKey })
    Target Modelの外部キーとSourceModalのプライマリキーの関連付けhasOneを持ってTarget Modelの別名asを構成し、Target Modelの外部キー名を設定し、デフォルトではforeignKeyにSourceModelの関連キー名を配置し、デフォルトではSourceModel.primryKeyとする.
    ここでasの値はkeyのデフォルトに影響しません.
    Many-to-Many
    belongs ToMany
    SourceModel.belongsToMany(TargetModel, { through: AssociationModel, as, foreignKey, otherKey })
    中間テーブルによって関連付けられた${SourceModel.name}+${SourceMode.primaryKey}中間テーブルAsociation Modelの別名soruceKeyは、Asociation ModelにおけるSourceModelプライマリキーに関連する外部キー名を設定し、デフォルトではSourceModel.name+SourceModel.primation asにAsociation Modelに設定されている.
    ここでasの値はkeyのデフォルトに影響しません.
    User.belongsToMany(Role, { through: RoleAssignment, foreignKey: 'userId', otherKey: 'roleId' })
    
    user.findAll({
      include: [{
        model: Role,
        through: {
          // attributes: [], // uncomment this line to hide RoleAssignment as attribute in result in target model
          model: RoleAssignment,
          where
        }
      }]
    })
    結果を返します
    const result = [{
      id: '',
      userName: '',
      gender: '',
      roles: [{
        id: '',
        roleName: '',
        ...
        RoleAssignment: {
          id: '',
          roleId: '',
          userId: '',
          ...
        }
      }]
    }]