mphasize/sails-generate-ember-blueprints

slug vs primaryKey

Closed this issue · 4 comments

I'd like the following route:
app.example/username
to call the following endpoint:
api.example/user/username

But the current findOne method only supports pk’s for looking up records, therefore I tweaked the findOne method so it works the way i want to, like so:

// Custom User slug implementation
// When the model is `user` and the pk is
// not a digit, we'll assume its a username
// slug and query that in stead.

// original:
// var query = Model.findOne( pk );

// Ensure a model can be deduced from the request options.
var modelName = req.options.model || req.options.controller;
if ( !modelName ) throw new Error( util.format( 'No "model" specified in route options.' ) );

var query;
if(modelName === 'user' && (/\D/).test(pk)) {
    query = Model.findOne({ username: pk });
} else {
    query = Model.findOne( pk );
}
// end slugism

Could you perhaps suggest a more elegant way of working with slugs?

PS I'm really glad you continued working on this project. Just upgraded to latest and things feel much more mature now. Awesome!

Well, I am hoping to eventually release an application I'm working on that is based on this project, so I have an interest in evolving it. :-)

Concerning the slugs I would suggest to create a policy that transforms the slug into a primary key (basically the code you already got.) As far as I know, the original Sails blueprints do not handle slugs and I think we should stay as close as possible to the original Sails functionality (thus acting as a plug-in replacement).

I even abandoned my ideas to add additional beforeFind hooks in the blueprints when I found out that it's possible to create them as a Policy.

@timohofmeijer Did you manage to get slugs working with a policy?

@mphasize I wanted to use ember-data’s store to find records like so: this.store.find('user', 'timo') (api/users/timo), while id was still the primary key in my sails user model. I changed your findOne blueprint to lookup records by their slug whenever the pk was not an integer, which worked just fine if it wasn‘t for ember-data throwing errors (Expected an object asdatain a call topushfor ...).

I initially thought issue #31 was to blame for this error, but @bmac pointed out ED assumes that timo is the id when querying like so: this.store.find('user', 'timo'). This made me switch to querying the store like so: this.store.find('user', { username: 'timo' }) and thats where my slug adventure ended ;-)

@timohofmeijer Thanks for your answer! I guess that will be helpful for other people who want to do something similar.