User model
Although the ultimate goal of the previous post is to make a signup page for our site, it would do little good now to accept information for new users: we don’t currently have any place to put it. Thus, the first step in signing up users is to make a data structure to capture and store their information.
Database migrations
Create the database configuration with generate database
command.
~/sample_app $ trainjs generate database sqlite
create .sequelizerc
create config/database.json
The analogous command for making a model is generate model
, which we can use to generate a User model with name
and email
attributes.
~/sample_app $ trainjs generate model User name:string email:string
create app/models/user.js
create db
create db/migrate
create db/migrate/20160119110300_create_users.js
create test/models/user_test.js
Install all modules listed as dependencies in package.json
~/sample_app $ npm install
One of the results of the generate command is a new file called a migration. Migrations provide a way to alter the structure of the database incrementally, so that our data model can adapt to changing requirements. In the case of the User model, the migration is created automatically by the model generation script; it creates a user
table with two columns, name
and email
db/migrate/[timestamp]_create_users.js
module.exports = {
up: function(migration, DataTypes, done) {
// add altering commands here, calling 'done' when finished
migration.createTable('user', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
name: DataTypes.STRING,
email: DataTypes.STRING,
createdAt: DataTypes.DATE,
updatedAt: DataTypes.DATE,
});
done();
},
down: function(migration, DataTypes, done) {
// add reverting commands here, calling 'done' when finished
done();
}
}
Note that the name of the migration file is prefixed by a timestamp based on when the migration was generated. We can run the migration, known as migrating up
, using the sequelize
command
~/sample_app $ sequelize db:migrate
Loaded configuration file "config/database.json".
Using environment "development".
Using gulpfile /usr/lib/node_modules/sequelize-cli/lib/gulpfile.js
Starting 'db:migrate'...
Finished 'db:migrate' after 411 ms
== 20160119110300_create_users: migrating =======
== 20160119110300_create_users: migrated (0.272s)
Creating user objects
Using node
console to explore data models.
~/sample_app $ node
Load config file and models file
> require('trainjs').initServer()
In the console session, we created a new user object with User.build
> User.build()
When called with no arguments, User.build
returns an object with all NULL attributes. Now we created a user with name and email attributes.
> var user = User.build({name: "Dang Thanh", email: "[email protected]"})
undefined
> user
{ dataValues: { id: null, name: 'Dang Thanh', email: '[email protected]' },
...
User.build
only creates an unsaved object. In order to save the User object to the database, we need to call the save method on the user variable.
> user.save()
Executing (default): INSERT INTO `user` (`id`,`name`,`email`,`updatedAt`,`createdAt`) VALUES (NULL,'Dang Thanh','[email protected]','2016-01-20 09:39:59.293 +00:00','2016-01-20 09:39:59.293 +00:00');
You may have noticed that the new user object had null
values for the id
and the magic columns createdAt
and updatedAt
attributes. Let’s see if our save changed anything
> user
{ dataValues:
{ id: 1,
name: 'Dang Thanh',
email: '[email protected]',
updatedAt: Wed Jan 20 2016 16:39:59 GMT+0700 (ICT),
createdAt: Wed Jan 20 2016 16:39:59 GMT+0700 (ICT) },
...
We see that the id has been assigned a value of 1, while the magic columns have been assigned the current time and date. As with the User class, instances of the User model allow access to their attributes using a dot notation
> user.name
'Dang Thanh'
> user.email
'[email protected]'
> user.updatedAt
Wed Jan 20 2016 16:39:59 GMT+0700 (ICT)
We can create an user into one step with User.create
> User.create({name: "A Nother", email: "[email protected]"})
Executing (default): INSERT INTO `user` (`id`,`name`,`email`,`updatedAt`,`createdAt`) VALUES (NULL,'A Nother','[email protected]','2016-01-20 09:50:40.137 +00:00','2016-01-20 09:50:40.137 +00:00');
> var foo
undefined
> User.create({name: "Foo", email: "[email protected]"}).then(function(data){ foo = data })
Executing (default): INSERT INTO `user` (`id`,`name`,`email`,`updatedAt`,`createdAt`) VALUES (NULL,'Foo','[email protected]','2016-01-20 09:53:15.966 +00:00','2016-01-20 09:53:15.966 +00:00');
The inverse of create is destroy
> foo.destroy()
Executing (default): DELETE FROM `user` WHERE `id` = 3
Finding user objects
Sequelize provides several options for finding objects. Let’s use them to find the first user we created while verifying that the third user (foo) has been destroyed. We’ll start with the existing user
> User.findById(1).then(function(data){ console.log(data) })
{ dataValues:
{ id: 1,
name: 'Dang Thanh',
email: '[email protected]',
createdAt: Wed Jan 20 2016 16:39:59 GMT+0700 (ICT),
updatedAt: Wed Jan 20 2016 16:39:59 GMT+0700 (ICT) },
...
Here we’ve passed the id of the user to User.find; Sequelize returns the user with that id.
Let’s see if the user with an id of 3 still exists in the database
> User.findById(3).then(function(data){ console.log(data) })
null
Since we destroyed our third user, Sequelize can’t find it in the database.
Sequelize also allows us to find users by specific attributes
> User.findOne( { where: {email: "[email protected]"} } ).then(function(data){ console.log(data) })
{ dataValues:
{ id: 1,
name: 'Dang Thanh',
email: '[email protected]',
createdAt: Wed Jan 20 2016 16:39:59 GMT+0700 (ICT),
updatedAt: Wed Jan 20 2016 16:39:59 GMT+0700 (ICT) },
...
Updating user objects
Once we’ve created objects, we often want to update them. There are two basic ways to do this. First, we can assign attributes individually
> user
{ dataValues:
{ id: 1,
name: 'Dang Thanh',
email: '[email protected]',
createdAt: Wed Jan 20 2016 16:39:59 GMT+0700 (ICT),
updatedAt: Wed Jan 20 2016 16:39:59 GMT+0700 (ICT) },
...
> user.email = "[email protected]"
'[email protected]'
> user.save()
Executing (default): UPDATE `user` SET `email`='[email protected]',`updatedAt`='2016-01-20 15:34:28.479 +00:00' WHERE `id` = 1
The second main way to update multiple attributes is to use update
> user.update({name: "The Dude", email: "[email protected]"})
Executing (default): UPDATE `user` SET `name`='The Dude',`email`='[email protected]',`updatedAt`='2016-01-20 15:36:21.866 +00:00' WHERE `id` = 1
> user.name
'The Dude'
> user.email
'[email protected]'