Skip to content

Fetch associations for an array of models when autoFetch is off (similar to Mongoose's populate) ?  #120

@cheapsteak

Description

@cheapsteak

I have two models with a many to many relationship, routes and stops (for buses)

given an api like below:

/routes   
/routes/12,13,22,555,103,23,19/stops  
/stops   
/stops/23,32/routes   

I don't want /routes nor /stops to autoload, there's too much data, but I do want /routes/:ids/stops to autoload, and same for /stops/:ids/routes.

Is this possible?

Also, what's a way to do it without using autoload?
I've gotten this far:

app.get( '/api/routes/:ids/stops', function (request, response){
    var ids = request.params.ids.split(',');
    return request.models.route
        .find({id: ids})
        .each(function (route) {
            route.getStops(function(err, stops){ 
                route.stops = stops; // <--- need to make sure this gets called before returning
            });
        })
        .get(function(routes) {
            return response.send( routes );
        });
});

but I'm currently stuck trying to figure out how to make sure all the route.getStops have returned before sending the response.

Would I need a promise library to deal with this?


edit: dug around the source, found this but I don't seem to be using it correctly

request.models.route.settings.set('instance.autoFetch', true);
request.models.stop.settings.set('instance.autoFetch', true);

setting this doesn't seem to affect anything


edit: setting it as an option passed to find doesn't seem to work either

return request.models.route.find({id: ids}, {autoFetch: true}, function(err, routes){
    return response.send( routes );
});

edit: ~~~possibly solved?~~~ (nvm, apparently this messes up caching)
changed line 245 of Model.js from

autoFetch      : (options.autoFetchLimit === 0 ? false : opts.autoFetch)

to

autoFetch      : (options.autoFetchLimit === 0 ? false : options.autoFetch)

to allow specifying autoFetch as an option when calling find.

was this a typo or was the autoFetch not intended to be override-able?


edit: apparently changing that messes up caching.

request.models.route.find({id: ids}, {autoFetch: false})

or

request.models.route.find({id: ids}, {autoFetch: true})

whichever one gets called first ends up determining autoFetch forever.

setting instance settings via request.models.model.settings.set didn't work either

app.get( '/api/routes/:ids', function (request, response){
    request.models.route.settings.set('instance.autoFetch', false); 
    request.models.route.find({id: ids}, {autoFetch: false})
}

app.get( '/api/routes/:ids/stops', function (request, response){
    request.models.route.settings.set('instance.autoFetch', true);
    request.models.route.find({id: ids}, {autoFetch: true})
});

The setting does change but it doesn't seem to affect the output

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions