Reference: https://gitter.im/balderdashy/sails?at=58be4b1af1a33b62758d57ea
Is there anyway that I can add a method to all routes?
Given a Sails app with two models User
and Pet
, how do we create a single controller action foo
and have it automatically run on requests for both /user/foo
and /pet/foo
?
There are a few ways to accomplish this, which differ between Sails v0.12.x and Sails 1.0, but the following approach should work with both.
This can be called anything; we'll use api/controllers/SharedController.js
.
Inside of api/controllers/SharedController.js
, we'll add our example foo
action, which will simply respond with the name of the relevant model and the number of attributes that model has.
module.exports = {
foo: function(req, res) {
// Get the model name from the route URL.
var modelName = req.param('model');
// Make sure a Sails model with that name exists. If not, just respond with a 404.
if (!req._sails.models[modelName]) {
return res.notFound();
}
// Get a reference to the Sails model.
var Model = req._sails.models[modelName];
// Respond with some info about the model.
res.send('Called the `foo` action for the `' + modelName + '` model which as ' + Object.keys(Model.attributes).length + ' attributes.');
}
};
If you have the
sails
global turned on in your app, you can replacereq._sails
with justsails
.
By using a dynamic route parameter, we can route both /user/foo
and /pet/foo
to the foo
action. In config/routes.js
:
'GET /:model/foo': 'SharedController.foo'
Note that this will route
xyz/foo
,blag/foo
, etc. to thefoo
action as well, which is why the action checks first that themodel
param represents a valid Sails model.
I like the approach here. What if this were to be made a module to be installed via npm or its alternatives?