2

I'm building a relatively big NodeJS application, and I'm currently trying to figure out how to fetch the data I need from the DB. Here is a part of my models :

One user has one role, which has access to many modules (where there's a table role_modules to link roles and modules).

In Rails, I would do something like user.role.modules to retrieve the list of the modules he has access to. In NodeJS it's a bit more complicated. I'm using node-orm2 along with PostgreSQL. Here is what I have so far:

req.models.user.find({email: req.body.user}, function(err, user) {
  user[0].getRole(function(err, role) {
    role.getModules(function(err, modules) {
      var list_modules = Array();
      modules.forEach(function(item) {
        console.log(item);
        list_modules.push(item.name);
      })

But I can't do this, because item only contains role_id and module_id. If I want to have the name, I would have to do item.getModule(function() {...}), but the results would be asynchronous ... so I don't really see how I could end up with an array containing the names of the modules a user has access to ... have any idea?

Also, isn't that much slower than actually running a single SQL query with many JOIN? Because as I see it, the ORM makes multiple queries to get the data I want here...

Thank you!

Samuel Bolduc
  • 18,163
  • 7
  • 34
  • 55
  • As i understood, you want to reach module from user, right? Have you try on association in `node-orm2` ? – Hossein Mobasher Aug 03 '13 at 16:09
  • Well yes, that's what I'm using, but even with that I'm not quite sure how I can end up with an array of module names from the user, when all requests are async... Also I'm not sure about the good performance of this VS a plain old JOIN chain in SQL – Samuel Bolduc Aug 05 '13 at 13:47

1 Answers1

2

I wrote an ORM called bookshelf.js that aims to simplify associations and eager loading relations between models in SQL. This is what your query would probably look like to load the role & modules on a user given your description:

var Module = Bookshelf.Model.extend({
  tableName: 'modules'
});

var Role = Bookshelf.Model.extend({
  tableName: 'roles',

  modules: function() {
    return this.belongsToMany(Module);
  }
});

var User = Bookshelf.Model.extend({
  tableName: 'users'

  role: function() {
    return this.hasOne(Role);
  }
});


User.forge({email: req.body.user})
  .fetch({
    require: true,
    withRelated: ['role.modules']
  })
  .then(function(user) {

    // user, now has the role and associated modules eager loaded
    console.log(user.related('role'));
    console.log(user.related('role').related('modules'))

  }, function(err) {

    // gets here if no user was found.

  });

Might be worth taking a look at.

tgriesser
  • 2,808
  • 1
  • 22
  • 22
  • Is it possible in Bookshelf to query with constraints on related data? i.e. fetch({ require: true, withRelated: ['role.modules'] }).where('role.modules.length', '>', '1') (pseudo-code :)) – Yngve B-Nilsen Jan 17 '14 at 13:27