Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modified the way to add singleton resources. #8

Merged
merged 4 commits into from
Oct 8, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 18 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,23 +60,24 @@ http://railwayjs.com/routing.html

### Singleton resources

To create a singleton resource, set the singleton_for property of the
params hash to the resource you want the singleton resource to map to.

Example usage:

map.resources('users');
map.resources('account', {
singleton_for: 'users',
middleware: function(req, res, next) {
// Set the id parameter since we don't get it from the URL
// like is usually the case for normal resources.
if(req.user)
req.params.id = req.user.id;
else
return res.redirect('/login');
next();
}});
Example:

map.resource('account');

Will generate the following routes:

GET /account account#show
POST /account account#create
GET /account/new account#new
GET /account/edit account#edit
DELETE /account account#destroy
PUT /account account#update

Singleton resources can also have nested resources. For example:

map.resource('account', function(account) {
account.resources('posts');
});

## Example app

Expand Down
29 changes: 29 additions & 0 deletions examples/singleton/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
var express = require('express')
, Map = require('../../lib/railway_routes').Map;

var app = express();

app.use(app.router);

var map = new Map(app, function(namespace, controller, action) {
console.log(arguments);
});

map.resources('users', function(user) {
map.resources('posts', function(post) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it should be user.resources('posts',...?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops yeah :/

map.resources('comments');
});
//user.singleton('account');
});

map.resource('account', {controller: 'users'}, function(account) {
map.resources('posts', function(post) {
map.resources('comments');
});
});

console.log(app.routes);

app.listen(3000, function(){
console.log('Express server listening at http://localhost:3000');
});
35 changes: 32 additions & 3 deletions lib/railway_routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,11 +224,27 @@ Map.prototype.resources = function (name, params, actions) {
actions = params;
params = {};
}

// If resource uses the path param, it's subroutes should be
// prefixed by path, not the resource's name
// i.e.:
// map.resource('users', {path: ':username'}, function(user) {
// user.resources('posts);
// });
//
// /:username/posts.:format?
// /:username/posts/new.:format?
// etc.
var prefix = params.path ? params.path : name;

// we have bunch of actions here, will create routes for them
var activeRoutes = getActiveRoutes(params);
// but first, create subroutes
if (typeof actions == 'function') {
this.subroutes(name + '/:' + (singularize(name) || name) + '_id', actions);
if (params.singleton)
this.subroutes(prefix, actions); // singletons don't need to specify an id
else
this.subroutes(prefix + '/:' + (singularize(name) || name) + '_id', actions);
}
// now let's walk through action routes
for (var action in activeRoutes) {
Expand Down Expand Up @@ -260,7 +276,7 @@ Map.prototype.resources = function (name, params, actions) {
// params.path setting allows to override common path component
var effectivePath = (params.path || name) + path;

var controller = (params.singleton_for) ? params.singleton_for : name;
var controller = params.controller || name;

// and call map.{get|post|update|delete}
// with the path, controller, middleware and options
Expand Down Expand Up @@ -295,7 +311,7 @@ Map.prototype.resources = function (name, params, actions) {
, 'update': 'PUT /'
};

if(params.singleton_for)
if (params.singleton)
availableRoutes = availableRoutesSingleton;

// 1. only
Expand Down Expand Up @@ -348,6 +364,19 @@ Map.prototype.resources = function (name, params, actions) {
}
};

Map.prototype.resource = function(name, params, actions) {
var self = this;
// params are optional
params = params || {};
// if params arg omitted, second arg may be `actions`
if (typeof params == 'function') {
actions = params;
params = {};
}
params.singleton = true;
return this.resources(name, params, actions);
}

/*
* Namespaces mapper.
*
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
"engines": {
"node": ">= 0.4.0"
},
"dependencies": {},
"dependencies": {
"express": "3.x"
},
"devDependencies": {
"nodeunit": "*"
}
Expand Down