orm - Sails.js + Waterline: Many-to-Many through association -
i'm new sails.js (v0.10.5) , waterline orm. have 3 tables in database: users (id, name), roles(id, alias) , join table users_roles(user_id, role_id). it's important not change table names , field names in database. want policy entity join entity between user , role. here mapping code:
//user.js module.exports = { tablename: 'users', autocreatedat: false, autoupdatedat: false, attributes: { id: { type: 'integer', required: true }, name: { type: 'string' }, roles: { collection: 'role', via: 'users', through: 'policy' }, } } //role.js module.exports = { tablename: "roles", autocreatedat: false, autoupdatedat: false, attributes: { id: { type: 'integer', required: true }, alias: { type: 'string', required: true }, users: { collection: 'user', via: 'roles', through: 'policy' } } } //policy.js module.exports = { tablename: "users_roles", tables: ['users', 'roles'], junctiontable: true, autocreatedat: false, autoupdatedat: false, attributes: { user: { columnname: 'user', type: 'integer', foreignkey: true, references: 'user', on: 'id', via: 'role', groupby: 'user' }, roles: { columnname: 'role', type: 'integer', foreignkey: true, references: 'role', on: 'id', via: 'user', groupby: 'role' } } }
but when trying access roles atribute in controller
user.findone({id: 1}).populate('roles').exec(function(err, user) { console.log(json.stringify(user.roles)); });
this returns
[]
and
user.findone({id: 1}).populate('roles').exec(function(err, user) { console.log(json.stringify(user)); });
returns
{"id":1,"name":"test", "roles":[]}
i checked twice user, role , association between them exists in database. mistake?
i have found way solve problem. it's not want, works. first: join entity:
//policy.js module.exports = { tablename: "users_roles", autopk: false, attributes: { id: { type: 'integer', primarykey: true, autoincrement: true, }, user: { columnname: 'user_id', model: 'user' }, role: { columnname: 'role_id', model: 'role' } }, //tricky method users specified role_id //or roles specified user_id get: function(id, modificator, cb) { var fields = ['user', 'role']; if (fields.indexof(modificator) < 0) { cb(new error('no such modificator in policy.get()'), null); } var inversedfield = fields[(fields.indexof(modificator) + 1) % 2]; var condition = {}; condition[inversedfield] = id; this.find(condition).populate(modificator).exec(function(err, policies) { if (err) { cb(err, null); return; } var result = []; policies.foreach(function(policy) { result.push(policy[modificator]); }); cb(null, result); return; }); } }
as see, added id field entity (and db table users_roles too), it's not great solution.
//user.js module.exports = { tablename: 'users', autopk: false, attributes: { id: { type: 'integer', primarykey: true, autoincrement: true, unique: true, }, name: { type: 'string' }, policies: { collection: 'policy', via: 'user' } } }
and role entity:
//role.js module.exports = { tablename: 'roles', autopk: false, attributes: { id: { type: 'integer', primarykey: true, autoincrement: true, }, alias: { type: 'string', required: true, unique: true, }, policies: { collection: 'policy', via: 'role' } } }
that's how roles specified user_id:
... id = req.session.me.id; //user_id here policy.get(id, 'role', function(err, roles) { var isadmin = false; roles.foreach(function(role) { isadmin |= (role.id === 1); }); if (isadmin) { next(null); return; } else { return res.redirect('/login'); } }); ...
maybe it'll usefull =)
Comments
Post a Comment