visionmedia / express-resource

Resourceful routing for Express
1.41k stars 140 forks source link

custom collection actions #39

Open icambron opened 12 years ago

icambron commented 12 years ago

Suppose I've done something like:

var users = {

  show: function(req, res){
    //do something
  },

  me: function(req, res){
    //do something
  },

  load : function(id, fn){
    User.findById(id, fn);
  }
};

var userResource = app.resource('users', users);
userResource.map('get', 'me', users.me) //expecting /users/me to do something

That doesn't work. It seems to think that "me" is the ID and passes it to load, thinking it's going to invoke show. In fact, I don't know how it would know any better. So I'm thinking there's no way to do custom collection actions; you can only do custom member actions.

So first off, is that right? If so, is this something I should patch?

sbugzu commented 12 years ago

I found that it's priority problem of register, I have just a temporary solution. modify the sourcecode

//default actions
for (var i=0, key; i < orderedActions.length; i++) {  
  key = orderedActions[i];
  if (actions[key]) this.mapDefaultAction(key, actions[key]);
}

to

//default actions
_this = this;
setTimeout(function() {
  for (var i=0, key; i < orderedActions.length; i++) {
    key = orderedActions[i];
    if (actions[key]) _this.mapDefaultAction(key, actions[key]);
  }
}, 1000);

The purose of modification is delayed loading default actions, and loading custom router at first. You can change the setTimeout time according to the actual.

wright-io commented 12 years ago

This really does seem like a valid issue. Is the code above really the recommended way to fix it? The problem is that adding something like

userResource.map('get', '/logout', users.logout)

gets blocked by the :show action (expecting that the '/logout' string is an id).

What is the correct way to avoid this conflict?