Skip to content Skip to sidebar Skip to footer

Returning a Model Instance and Quyerying Again Sequelize

Sequelize is a popular, like shooting fish in a barrel-to-use JavaScript object relational mapping (ORM) tool that works with SQL databases. It'due south fairly straightforward to offset a new project using the Sequelize CLI, but to truly take advantage of Sequelize'due south capabilities, you'll want to define relationships betwixt your models.

In this walkthrough, nosotros'll set up a Sequelize project to assign tasks to particular users. We'll utilize associations to ascertain that human relationship, and so explore ways to query the database based on those associations.

Let's start by installing Postgres, Sequelize, and the Sequelize CLI in a new project binder:

          mkdir sequelize-associations
cd sequelize-associations
npm init -y
npm install sequelize pg
npm install --salvage-dev sequelize-cli

Next, let's initialize a Sequelize project, so open up the whole directory in our lawmaking editor:

          npx sequelize-cli init
lawmaking .

To learn more well-nigh whatsoever of the Sequelize CLI commands below, run across:
Getting Started with Sequelize CLI

Let'south configure our Sequelize project to work with Postgres. Discover config.json in the /config directory and supercede what'due south there with this code:

          {
"development": {
"database": "sequelize_associations_development",
"host": "127.0.0.1",
"dialect": "postgres"
},
"exam": {
"database": "sequelize_associations_test",
"host": "127.0.0.1",
"dialect": "postgres"
},
"product": {
"database": "sequelize_associations_production",
"host": "127.0.0.one",
"dialect": "postgres"
}
}

Cool, at present nosotros can tell Sequelize to create the database:

          npx sequelize-cli db:create        

Next we volition create a User model from the command line:

          npx sequelize-cli model:generate --name User --attributes firstName:cord,lastName:string,electronic mail:string,password:string        

Running model:generate automatically creates both a model file and a migration with the attributes nosotros've specified. You tin notice these files within your project directory, only there's no need to change them right at present. (Later, we'll edit the model file to define our associations.)

Now we'll execute our migration to create the Users table in our database:

          npx sequelize-cli db:migrate        

Now let's create a seed file:

          npx sequelize-cli seed:generate --proper name user        

You will see a new file in /seeders. In that file, paste the following code to create a "John Doe" demo user:

          module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.bulkInsert('Users', [{
firstName: 'John',
lastName: 'Doe',
e-mail: 'demo@demo.com',
password: '$321!pass!123$',
createdAt: new Engagement(),
updatedAt: new Date()
}], {});
},
down: (queryInterface, Sequelize) => {
return queryInterface.bulkDelete('Users', null, {});
}
};

Once we've saved our seed file, allow's execute it:

          npx sequelize-cli db:seed:all        

Driblet into psql and query the database to see the Users table:

          psql sequelize_associations_development
SELECT * FROM "Users";

Defining associations

Peachy! We've got a working User model, but our John Doe seems a little bored. Let's give John something to do by creating a Chore model:

          npx sequelize-cli model:generate --name Job --attributes title:cord,userId:integer        

Just as with the User model higher up, this Sequelize CLI control will create both a model file and a migration based on the attributes we specified. Just this time, we'll demand to edit both in order to necktie our models together.

First, notice task.js in the /models subdirectory within your projection directory. This is the Sequelize model for tasks, and you'll see that the sequelize.define() method sets up title and userId equally attributes, but as we specified above.

Below that, you'll run across Chore.associate. It's currently empty, but this is where we'll really tie each task to a userId. Edit your file to await like this:

          module.exports = (sequelize, DataTypes) => {
const Task = sequelize.ascertain('Task', {
championship: DataTypes.STRING,
userId: DataTypes.INTEGER
}, {});
Chore.associate = function(models) {
// associations can be defined hither
Chore.belongsTo(models.User, {
foreignKey: 'userId',
onDelete: 'CASCADE'
})
};
return Task;
};

What do those changes exercise? Task.belongsTo() sets upwardly a "belongs to" relationship with the User model, meaning that each task volition be associated with a specific user.

We do this by setting userId as a "strange key," which means it refers to a key in another model. In our model, tasks must belong to a user, and then userId will correspond to theid in a particular User entry. (The onDelete: 'CASCADE' configures our model then that if a user is deleted, the user'south tasks will exist deleted too.)

We also need to change our User model to reflect the other side of this human relationship. Find user.js and change the department under User.acquaintance so that your file looks similar this:

          module.exports = (sequelize, DataTypes) => {
const User = sequelize.define('User', {
firstName: DataTypes.Cord,
lastName: DataTypes.STRING,
password: DataTypes.Cord,
email: DataTypes.STRING
}, {});
User.associate = function(models) {
// associations can be defined here
User.hasMany(models.Task, {
foreignKey: 'userId',
})
};
return User;
};

For this model, nosotros've set upward a "has many" relationship, meaning a user can accept multiple tasks. In the .hasMany() method, the foreignKey option is set to the name of the key on the other table. In other words, when theuserId on a job is the same equally the id of a user, we have a match.

Nosotros still have to brand one more than change to set up our relationship in the database. In your project's/migrations folder, you should see a file whose proper noun ends with create-task.js. Change the object labeled userId so that your file looks like the code below:

          module.exports = {
upward: (queryInterface, Sequelize) => {
render queryInterface.createTable('Tasks', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
title: {
blazon: Sequelize.String
},
userId: {
type: Sequelize.INTEGER,
onDelete: 'CASCADE',
references: {
model: 'Users',
key: 'id',
as: 'userId',
}
},
createdAt: {
allowNull: false,
type: Sequelize.Date
},
updatedAt: {
allowNull: imitation,
type: Sequelize.DATE
}
});
},
downward: (queryInterface, Sequelize) => {
return queryInterface.dropTable('Tasks');
}
};

The references section will prepare up the Tasks table in our database to reflect the same relationships we described above. Now we can run our migration:

          npx sequelize-cli db:migrate        

At present our John Doe is ready to take on tasks — but John notwithstanding doesn't have any actual tasks assigned. Allow'south create a task seed file:

          npx sequelize-cli seed:generate --name task        

Find the newly generated seed file and paste in the following to create a task:

          module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.bulkInsert('Tasks', [{
title: 'Build an app',
userId: 1,
createdAt: new Date(),
updatedAt: new Date()
}], {});
},
down: (queryInterface, Sequelize) => {
return queryInterface.bulkDelete('Tasks', cypher, {});
}
};

We'll gear up userId to 1 so that the chore will belong to the user we created earlier. Now we tin can populate the database.

          npx sequelize-cli db:seed:all        

Test the database:

          psql sequelize_associations_development
SELECT * FROM "Users" JOIN "Tasks" ON "Tasks"."userId" = "Users".id;

Querying via Sequelize

At present nosotros tin query our database for data based on these associations — and through Sequelize, we can practice it with JavaScript, which makes it piece of cake to comprise with a Node.js application. Let's create a file to hold our queries:

          affect query.js        

Paste the lawmaking below into your new file:

          const { User, Task } = require('./models')
const Sequelize = require('sequelize');
const Op = Sequelize.Op

// Detect all users with their associated tasks
// Raw SQL: SELECT * FROM "Users" Bring together "Tasks" ON "Tasks"."userId" = "Users".id;

const findAllWithTasks = async () => {
const users = await User.findAll({
include: [{
model: Chore
}]
});
console.log("All users with their associated tasks:", JSON.stringify(users, nix, four));
}

const run = async () => {
await findAllWithTasks()
await process.exit()
}

run()

The first three lines above import our User and Job models, along with Sequelize. Afterward that, we include a query office that returns every User along with that user'southward associated tasks.

Sequelize's .findAll() method accepts options as a JavaScript object. Above, we used the include option to have advantage of "eager loading" — querying data from multiple models at the same time. With this selection, Sequelize will return a JavaScript object that includes each User with all associated Job instances as nested objects.

Let's run our query file to run into this in action:

          node query.js        

Now it'due south articulate that our John Doe has a project to work on! We can use the same method to include the User when our query finds a Task. Paste the post-obit lawmaking into query.js:

          // Find a task with its associated user
// Raw SQL: SELECT * FROM "Tasks" Join "Users" ON "Users"."id" = "Tasks"."userId";

const findTasksWithUser = async () => {
const tasks = await Job.findAll({
include: [{
model: User
}]
});
console.log("All tasks with their associated user:", JSON.stringify(tasks, naught, 4));
}

Alter const run at the bottom of query.js by adding a line to telephone call findTasksWithUser(). Now run your file again in Node — each Job should include info for the User it belongs to.

The queries in this walkthrough make use of the .findAll() method. To learn more about other Sequelize queries, see: Using the Sequelize CLI and Querying

You can as well include other options aslope include to make more than specific queries. For example, below we'll use the where choice to find but the users named John while still returning the associated tasks for each:

          // Find all users named John with their associated tasks
// Raw SQL: SELECT * FROM "Users" WHERE firstName = "John" Join tasks ON "Tasks"."userId" = "Users".id;
const findAllJohnsWithTasks = async () => {
const users = await User.findAll({
where: { firstName: "John" },
include: [{
model: Chore
}]
});
console.log("All users named John with their associated tasks:", JSON.stringify(users, null, iv));
}

Paste the above into your query.js and modify const run to call findAllJohnsWithTasks() to try it out.

Now that you know how to apply model associations in Sequelize, you tin design your awarding to deliver the nested data you need. For your next step, you might decide to include more robust seed data using Faker or integrate your Sequelize application with Express to create a Node.js server!

This article was co-authored with Jeremy Rose, a software engineer, editor, and writer based in New York City.

More than info on Sequelize CLI:

  • Getting Started with Sequelize CLI
  • Using Sequelize CLI and Querying
  • Sequelize CLI and Express
  • Getting Started with Sequelize CLI using Faker
  • Build an Express API with Sequelize CLI and Express Router
  • Building an Express API with Sequelize CLI and Unit of measurement Testing!

Resource

  • https://sequelize.org/principal/manual/associations.html
  • https://sequelize.org/principal/manual/querying.html

berryspect1943.blogspot.com

Source: https://levelup.gitconnected.com/creating-sequelize-associations-with-the-sequelize-cli-tool-d83caa902233

ارسال یک نظر for "Returning a Model Instance and Quyerying Again Sequelize"