Включение данных через несколько связующих таблиц в Sequelize

#sequelize.js

#sequelize.js

Вопрос:

У меня есть следующие таблицы в базе данных MySQL:

  1. Полосы { идентификатор, имя, … }

  2. Люди { идентификатор, имя, … }

// Человек может быть в одной или нескольких группах // В группе есть один или несколько участников

  1. Участники группы { id, PersonID, bandId, isGuest, … }

  2. Инструменты { идентификатор, имя, … }

// Участник группы может играть на одном или нескольких инструментах в одной и той же конкретной группе // Несколько участников одной и той же группы могут играть на одних и тех же инструментах (например, два гитариста, все участники поют и т. Д.) // Человек может играть на разных инструментах в разных группах, в которых он или она состоит

  1. BandMembersRoles { id, MemberID, instrumentId, … }

Теперь, если я хочу получить всех участников из определенной группы, я бы написал запрос следующим образом:

 SELECT
    p.id AS personId,
    p.name,
    bm.isGuest,
    bm.id AS bandMemberId

FROM people AS p
JOIN BandMembers AS bm
    ON p.id = bm.Id
WHERE bm.bandId = 1
  

И в Sequelize тот же результат будет достигнут этим:

 // In models config:

db.People.belongsToMany(db.Bands, {
    through: 'BandMembers',
    foreignKey: "personId"
})

db.Bands.belongsToMany(db.People, {
    through: 'BandMembers',
    as: 'members',
    foreignKey: "bandId"
})

. . .


// In models config:

exports.findByBand = (req, res) => {
    Person.findAll({
    // This is a way to get band members only by specific band, please let me know if there is more elegant way for this:
        include: [{
            model: Band,
            attributes: [],
            where: { id: req.params.id }
        }],
        attributes: [
            ['id', 'personId'],
            [db.Sequelize.col('bands.BandMembers.id'), 'bandMemberId'],
            ['name'],
            [db.Sequelize.col('bands.BandMembers.isGuest'), 'isGuest']
        ]
    })
    .then(data => {
        // ...
    })
}
  

Теперь, если бы требовалась роль каждого участника группы в определенной группе, в PHP я бы создал такой код:

 // First, store the MySQL Query above in $personQuery

$memStmt = $conn->prepare($personQuery);
$memStmt->bindParam(':bandId', $bandId);
$memStmt->execute();

$memArr = array();

while ($mem = $memStmt->fetch(PDO::FETCH_ASSOC)) {
    extract($mem);

    // *** Get Roles
    $roleArr = array();

    $roleQuery = "SELECT
            r.id AS id,
            r.name
        FROM roles AS r
            JOIN BandMembersRoles AS bmr
                ON bm.id = r.memberId
            WHERE bm.id = :bandMemberId;

    $roleStmt = $conn->prepare($roleQuery);
    $roleStmt->bindParam(':m2b_id', $m2b_id);
    $roleStmt->execute();

    while ($role = $roleStmt->fetch(PDO::FETCH_ASSOC)) {
        extract($role);

        $roleItem  = array(
            'id' => (int)$id,
            'name' => $name
        );

        array_push($roleArr, $roleItem);
    }
    // *** End of Get Roles

// and the add it to member object...
  

. . .

Итак, мой вопрос: возможно ли в Sequelize включать инструменты участника группы с помощью некоторого кода включения или любым другим способом?

Спасибо!

Комментарии:

1. вы можете сделать это с помощью relations и foreign_key like db.People.hasMany(db.Instruments, { foreignKey: "personId" }) , и вы должны включить модель в свой запрос

2. Между людьми и инструментами нет прямой связи. Они связаны в контексте группы, в которой они находятся. Каждый человек может быть в нескольких группах, и их роли в разных группах могут быть разными. Итак, на самом деле схема такова: есть люди, и есть группы, есть таблица связей, которая соединяет людей и группы (отношение «многие ко многим»), и у этой таблицы связей есть свой идентификатор, назовем его p2b_id (продолжение следует …)

3. […продолжение] И затем есть таблица инструментов, которая содержит список всех доступных инструментов, и другая таблица ссылок, которая соединяет инструменты с людьми в диапазонах, а не с людьми как таковыми. Т.е. Внешний ключ внутри этого пользователя, подключенного к человеку в группе, НЕ является идентификаторомчеловека в таблице People, но его идентификатор в первой связующей таблице (person-to-band), которую мы назвали p2b_id.