5

Is there a way to have an action/function executed before each and all actions defined in a Sails controller? Similar to the beforeCreate hooks in the models.

For example in my DataController, I have the following actions:

module.exports = {
  mockdata: function(req, res) {
    var criteria = {};

    // collect all params
    criteria = _.merge({}, req.params.all(), req.body);
    //...some more login with the criteria...
  },
  getDataForHost: function(req, res) {
    var criteria = {};

    // collect all params
    criteria = _.merge({}, req.params.all(), req.body);
    //...some more login with the criteria...
  }
};

Can I do something like the following:

module.exports = {
  beforeAction: function(req, res, next) {
    var criteria = {};

    // collect all params
    criteria = _.merge({}, req.params.all(), req.body);
    // store the criteria somewhere for later use
    // or perhaps pass them on to the next call
    next();
  },

  mockdata: function(req, res) {
    //...some more login with the criteria...
  },
  getDataForHost: function(req, res) {
    //...some more login with the criteria...
  }
};

Where any call to any action defined will pass through the beforeAction first?

Nazar
  • 1,769
  • 1
  • 15
  • 31
tuvokki
  • 720
  • 1
  • 10
  • 18

2 Answers2

3

You can use policies here.

For example, create your custom policy as api/policies/collectParams.js:

module.exports = function (req, res, next) {
    // your code goes here
};

Than you can specify if this policy should work for all the controllers/actions, or only for specific ones in config/policies.js:

module.exports.policies = {
    // Default policy for all controllers and actions
    '*': 'collectParams',

    // Policy for all actions of a specific controller
    'DataController': {
        '*': 'collectParams'
    },

    // Policy for specific actions of a specific controller
    'AnotherController': {
        someAction: 'collectParams'
    }
};

Sometimes you may need to know, what is the current controller (from your policy code). You can easily get it in your api/policies/collectParams.js file:

console.log(req.options.model);      // Model name - if you are using blueprints
console.log(req.options.controller); // Controller name
console.log(req.options.action);     // Action name
Nazar
  • 1,769
  • 1
  • 15
  • 31
  • Great! Thanks. One more addition to this. It is possible to chain policies in a defined order. As per the docs instead of adding a specific policy, you can add an array e.g. to the edit method `edit: ['isAdmin', 'isLoggedIn']` If an action is explicitly listed, its policy list will override the default list. – tuvokki Apr 16 '15 at 14:46
2

Yes, you can use policies as a beforeAction.

The docs show that its used for authentication, but It can basically be used for your purposes. You just put your before action in a policy.

http://sailsjs.org/#!/documentation/concepts/Policies

Meeker
  • 5,979
  • 2
  • 20
  • 38