daniel gon
daniel gon

Reputation: 159

adding functions to a knex/bookshelf model in node/express

I have a model like this:

const User = db.Model.extend({
    tableName: 'users',
    hasSecurePassword: true
});

module.exports = User;

With this I can do things like

const User      = require("../models/user");

 User.fetchAll({columns:['id','email']}).then((data) => {
        res.json(data);
    }).catch(err => {
        res.json(err);
    });

What if I want to add costume functions to my model such as:

var connection  = require('./dbconnection.js');
var User = db.Model.extend({
    tableName: 'users',
    hasSecurePassword: true
});


User.getUsers = (callback) => {
    if (connection) {
        const newLocal = "select * FROM users";
        connection.query(newLocal, (err,rows,fields) => {
            if (err) {
                return res.sendStatus(500);
            } else {
                callback(null,rows);
            }
        });
    }
};

module.exports = User;

And then do something like:

 const User      = require("../models/user");
 User.getUsers((err,data) => {
    res.status(200).json(data);
});

Is this posible? Or should I just conform with the bookshelf functions? Right now the error I get is connection.query is not a function

And models/dbconnection.js is:

const mysql = require('mysql');
port = process.env.PORT || 3333;


if (port == 3333) {
    var connection = mysql.createConnection({
        host: process.env.DB_HOST,
        port: process.env.DB_PORT,
        user: process.env.DB_USER,
        password: process.env.DB_PASSWORD,
        database: process.env.DB_NAME,
        insecureAuth: true
    });
} else {
    console.log("Error");
}

connection.connect();
module.exports.connection = connection;

Upvotes: 0

Views: 1242

Answers (1)

zerosand1s
zerosand1s

Reputation: 750

Yes, you can add your custom functions to bookshelf models in two different ways.

  1. Instance methods

For example, you want to return user's full name, your User model will look something like this

const User = db.Model.extend({
    tableName: 'users',
    hasSecurePassword: true,

    //be careful here, if you use arrow function `this` context will change 
    //and your function won't work as expected

    returnFullName: function() {
       return this.get('firstname') + this.get('lastname');
    }
});

module.exports = User;

then you will call this function like this

User.forge().where({id: SOME_ID}).fetch()
    .then(function(user) {
        var fullName = user.returnFullName();
    });
  1. Class methods

For example, you want to return user's email based on username, your User model will look something like this

const User = db.Model.extend({
    tableName: 'users',
    hasSecurePassword: true
}, {

    getUserEmail: function(SOME_USERNAME) {
        return User.forge().where({username: SOME_USERNAME}).fetch()
            .then(function (user) {
                if(user) {
                    return Promise.resolve(user.get('email'));
                } else {
                    return Promise.resolve(null);
                }
            });
    }        
});

module.exports = User;

then you can call this function like

User.getUserEmail(SOME_USERNAME)
    .then(function(email) {
        console.log(email);
    });

Upvotes: 2

Related Questions