JugglingDB

The missing documentation

Methods, setters and so on

Class methods

Static methods (methods with class scope) could be added declaring a function as a member of the model, as follows. Inside a class method, other class methods can be called using the model name as usual.

var User = db.define("user.user", {
    id: { type: Number },
    username: { type: String },
    type_id: { type: String },
});

User.findByTypeId = function (type_id, cb) {
    User.findOne({where: {type_id: type_id}}, cb);
}

Instance methods

Instance methods can be added with prototype. Inside instance methods, the object itself can be called with this inside.

var User = db.define("user.user", {
    id: { type: Number },
    username: { type: String },
    type_id: { type: String },
});

User.prototype.fullUsername = function () {
    return this.username + ":" + this.type_id;
}

Setters

A custom setter can be defined as a virtual attribute for a model:

Role.setter.permissions = function (permissions) {
    this._permissions = permissions;
}

Relations

When specifying model relations, the ORM will define some automatic methods for set and get the related objects. The relations can be of two types: hasMany and belongsTo. For instance, an author has many books, and each book belongs to an author. So we should mark the relation as “belongsTo” from the books side, since the books table will have the author id as a foreign key. From the authors side, we should specify a “hasMany” association with books.

var Author = db.define("authors", {
    id: { type: Number },
    name: { type: String }
});
Author.hasMany(Book, {as: 'books',  foreignKey: 'author_id'});

var Book = db.define("books", {
    id: { type: Number },
    title: { type: String }
    author_id: { type: Number },
});
Book.belongsTo(Author, {as: 'author', foreignKey: 'author_id'});

To get an author books, we can use the automatic asynchronous getter as follows:

author.books(function (err, books) {
    console.log(books);
});

And also we can get a book author by using:

book.author(function (err, author) {
    console.log(author);
});

Validations

For format-related validations (length, size, data type...) that doesn’t require additional queries, you should use a synchronous validator. If the validator requires an asynchronous operation, you should use an asynchronous validator. You can use the built-in validators or write your own. Validators are executed when saving the instance (with .save, .updateAttributes, .create and this kind of methods), or when explicitly executing .isValid method.

Official documentation is in: http://jsdoc.info/1602/jugglingdb/validatable.html.

Asynchronous validations

The method validateAsync can be used to perform an asynchronous-custom validation. For instance:

Role.validateAsync('is_administrator', function (err, done) {
    self = this;
    this.constructor.find(this.id, function (error, previous) {
        if (previous) {
            if (previous.is_administrator !== self.is_administrator) {
                err();    
            }
        } else {
            err();
        }
        done();
    });
}, "can’t change this value");

Getting the validations results

If the validation fails, the ORM returns a Validation error as a result of the .save method. Also, will include an array with the erros as result.errors.

app.post('/roles', checkAuth, function (req, res, next) {
    var newRole = new Role(req.body);
    newRole.company_id = req.user.id_company;
    newRole.save(function (err, result) {
        if (err) {
            console.log(err);
            console.log(result.errors);
            next(new APIError('orm', err, result));
        } else {
            Http.sendCreated(req, res, result);
        }
    });
});