Atualizado: 02/01/2025

Relacionamento Um-para-Um (One-to-One) com Sequelize no Node.js

Um relacionamento Um-para-Um indica que uma entidade pode possuir outra entidade em uma única instância. Por exemplo, um usuário pode ter uma conta em um determinado serviço. Por outro lado, uma conta só pode pertencer a um único usuário.

Para criar esse tipo de relacionamento entre modelos no Sequelize, utilizamos o método hasOne(). Vamos definir os modelos de usuário e conta como exemplo:

const Sequelize = require("sequelize");

const sequelize = new Sequelize("service_db", "root", "123456", {
    dialect: "mysql",
    host: "localhost",
    define: {
        timestamps: false
    }
});

const User = sequelize.define("user", {
    id: {
        type: Sequelize.INTEGER,
        autoIncrement: true,
        primaryKey: true,
        allowNull: false
    },
    name: {
        type: Sequelize.STRING,
        allowNull: false
    },
    age: {
        type: Sequelize.INTEGER,
        allowNull: false
    }
});

const Account = sequelize.define("account", {
    id: {
        type: Sequelize.INTEGER,
        autoIncrement: true,
        primaryKey: true,
        allowNull: false
    },
    email: {
        type: Sequelize.STRING,
        allowNull: false
    }
});

User.hasOne(Account, { onDelete: "cascade" });

sequelize.sync({ force: true }).then(() => {
    console.log("Tables have been created");
}).catch(err => console.log(err));

Neste caso, o modelo User é considerado o principal, e o modelo Account é o dependente. Por isso, o método hasOne() é chamado no modelo User, e o modelo Account é passado como o primeiro parâmetro. Embora, neste caso, a distinção entre o modelo principal e o dependente seja relativamente arbitrária, o segundo parâmetro do método define a configuração da relação, incluindo a exclusão em cascata.

Ao executar este código, serão criadas as seguintes tabelas no MySQL:

CREATE TABLE IF NOT EXISTS `users` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT, 
`name` VARCHAR(255) NOT NULL, 
`age` INTEGER NOT NULL
);

CREATE TABLE IF NOT EXISTS `accounts` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT, 
`email` VARCHAR(255) NOT NULL, 
`userId` INTEGER REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
);

Como podemos ver, a tabela accounts inclui uma coluna adicional chamada userId, que estabelece a ligação com a tabela users.

Adicionando e Obtendo Dados Relacionados

Para configurar os dados relacionados, usamos o método setNomeDoModelo. Por exemplo, vamos adicionar um usuário e sua respectiva conta:

// adicionando usuário
User.create({ name: "Tom", age: 39 })
.then(user => {
    // adicionando conta
    Account.create({ email: "tom@mimimail.com" }).then(account => {
        // associando a conta ao usuário
        user.setAccount(account).catch(err => console.log(err));
    });
}).catch(err => console.log(err));

Na prática, o método setAccount() executa um comando SQL UPDATE. Isso significa que as entidades que estamos associando já devem estar no banco de dados no momento da chamada deste método.

Para obter os dados relacionados, utilizamos o método getNomeDoModelo(). Por exemplo, vamos recuperar um usuário e sua conta:

// Obtendo usuário com id=1
User.findByPk(1).then(user => {
    if (!user) return console.log("User not found");
    user.getAccount().then(account => {
        console.log(user.name, "-", account.email);
    });
});

Neste caso, a saída no console será:

Tom - tom@mimimail.com

Podemos também obter todos os usuários, incluindo seus dados relacionados:

User.findAll({
    attributes: ["name"], // Incluindo a coluna name da tabela users
    include: [{
        model: Account,
        attributes: ["email"]  // Incluindo a coluna email da tabela accounts
    }]
}).then(users => {
    for (user of users) {
        console.log(user.name, "-", user.account.email);
    }
});
Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com