4

I have a problem to which I haven't been able to find an answer, even though I feel like this kind of a feature is very common in web applications. I'm fairly new to sails.js and web development in general, so feel free to correct me if I'm using wrong terminology or something.

I'm trying to alter the default functionality of sails.js blueprints, specifically 'find' for starters. I have a model, let's call it Book, that has an attribute 'user', which of course relates to a user. I'd like to filter results from localhost:[port]/book so that it only showed the books whose owner is the currently logged in user instead of showing all the books in the database.

So far I've tried checking out if policies would be the answer, but it seems like they produce very binary 'yes/no' results and can't be used for filtering. Then I tried overriding the default find action from the BookController, which kind of works, but I'm afraid I'm overriding some useful functionality since I don't fully understand the source code for the blueprints. Then I checked out the answer Adding missing request parameter before persistance in Sails.JS, and tried to add the owner as an URL query parameter, but found out I couldn't access the currently logged in user from routes.js and the idea was probably doomed from the start anyway.

Anyway, I was wondering if there was a smart way of handling this issue.

Community
  • 1
  • 1
Fissio
  • 3,748
  • 16
  • 31

2 Answers2

3

You can set a parameter inside your policies. Create a policy that runs on bookController.find and have it add the user id

Example (depends on your setup)

req.options.where.user = req.session.userId

Then when your blueprint runs, it will merge that userid with the other query attributes are passed in the params.

This is a starter example. You can expand this method to auto attach a user as well on create and update

config/policies.js

module.exports.policies = {'book.find':'attachUser'}

api/policies/attachUser.js

module.exports = function(req, res, next) {
    if(!req.options.where) req.options.where = {};
    req.options.where.user = req.session.userId
}
Robert Rossmann
  • 11,931
  • 4
  • 42
  • 73
Meeker
  • 5,979
  • 2
  • 20
  • 38
  • Alright, tried this and it's not working - I'm getting `Cannot set property 'user' of undefined`. The `req.options` doesn't seem to have attribute where at all, checked with `console.log(req.where)` in the `attachUser` policy. :/ – Fissio Jan 19 '15 at 13:36
  • Managed to get it working now, used `req.query.user = req.session.userId` instead. – Fissio Jan 19 '15 at 13:42
  • Your method will work but req.query.user will clash if someone attaches userId in the body. Just need to look out for that. The solution to your issue of it not working if fixed simply by defining the "where" object. I have edited it above to reflect that. – Meeker Jan 20 '15 at 16:30
  • 2
    Is there a way I could add functionality **after** the default execution of a Blueprint route? I want to "expand" the list of IDs returned by a controller. Question: http://stackoverflow.com/questions/29254826/populating-a-many-to-many-through-relation-in-sails-js – Karma Mar 30 '15 at 17:42
1

If you want to extend 'find' for example:

    find: function(req, res) {
        console.log("I am extended functionality")
        return sails.hooks.blueprints.middleware.find(req, res)
    }
NiceCodes
  • 11
  • 1
  • 1
    Where is supposed we have to place this piece code? I'm so interested on it – Jordi Aug 02 '19 at 09:32
  • This would be exactly what I need, however, it (no longer) seems to work. When I try this, I get an error "sails.hooks.blueprints.middleware.find is not a function". Could they have been moved somewhere else? – cygnus Dec 18 '22 at 14:58