1

I am trying out an MVC framework called railway.js (which sits on top of Node, Express, Mongoose, and Mongo).

I'm trying to get nested resources to work. I did the following scaffolding commands:

railway g scaffold user name email description 
railway g scaffold setup title description

Then I changed the routes.js file to:

exports.routes = function (map) {
  map.resources('users',function(user) {
    user.resources('setups');
  });
});

Doing railway r gives what I hoped for:

     user_setups GET    /users/:user_id/setups.:format?          setups#index
     user_setups POST   /users/:user_id/setups.:format?          setups#create
  new_user_setup GET    /users/:user_id/setups/new.:format?      setups#new
 edit_user_setup GET    /users/:user_id/setups/:id/edit.:format? setups#edit
      user_setup DELETE /users/:user_id/setups/:id.:format?      setups#destroy
      user_setup PUT    /users/:user_id/setups/:id.:format?      setups#update
      user_setup GET    /users/:user_id/setups/:id.:format?      setups#show
           users GET    /users.:format?                          users#index
           users POST   /users.:format?                          users#create
        new_user GET    /users/new.:format?                      users#new
       edit_user GET    /users/:id/edit.:format?                 users#edit
            user DELETE /users/:id.:format?                      users#destroy
            user PUT    /users/:id.:format?                      users#update
            user GET    /users/:id.:format?                      users#show

When I start up the server, add a user (happens to be 4e4b61e39f0d60d834000002), then go to http://localhost:3000/users/4e4b61e39f0d60d834000002/setups/new, it says I "cannot POST".

What am I missing? What's a good debugging approach?

I also tried adding an element into the UserSchema object: setups: [SetupSchema]. (Shouldn't we have to do this?)

Thanks in advance.

Christopher DuBois
  • 42,350
  • 23
  • 71
  • 93

2 Answers2

3

in your setup_controller:

before(loaduser);

...

function loadUser () {
User.findById(req.params.user_id, function (err, user) {
    if (err || !user) {
            redirect(path_to.users);
        } else {
            // this is where we make the actual user object accessible inside the view templating
            this.user = user;
            next();
        }
    }.bind(this));
}

in your setup/form.jade:

- form_for( setup, { method: 'POST', action: path_to.user_setups(user) }, function(form){
    //layout your form
- });
  • Would you still need to change path_to.setups to be path_to.user_setups in setup's controller and all the views? How does information about the user object get sent to and used by a view like new.ejs? Thanks! – Christopher DuBois Aug 17 '11 at 20:16
  • If the setup resource is nested under user, as it is in your example, then yes, you'd still need to specify the path_to.user_setups(user). The loadUser() before filter fetches and assigns the user to this.user, once that has happened inisde the the view templating you can just access "user" – Vince Scott Aug 20 '11 at 11:27
1

Look at file app/views/setups/new.ejs:

<h1>New setup</h1>

<% form_for(setup, {action: path_to.setups, method: 'POST', id: "setup_form"}, function (form) { %>
  <%- partial('setups/form.ejs', {locals: {form: form, setup: setup}}) %>
  <%- form.submit('Create setup') %> or
  <%- link_to('Cancel', path_to.setups) %>
<% });%>

It refers to not existing route path_to.setups, you have to change it to correct route path_to.user_setups:

<h1>New setup</h1>

<% form_for(setup, {action: path_to.user_setups(user), method: 'POST', id: "setup_form"}, function (form) { %>
  <%- partial('setups/form.ejs', {locals: {form: form, setup: setup}}) %>
  <%- form.submit('Create setup') %> or
  <%- link_to('Cancel', path_to.setups) %>
<% });%>

So, you will POST to /users/.../setups instead of POST to /users/.../setups/new.

Please note that you need pass user as first argument of path_to helper, so railway will build correct route for you.

Anatoliy
  • 29,485
  • 5
  • 46
  • 45
  • That makes sense. Regarding your note at the end, could you clarify where I need to make the necessary change? I made the first change and I get the same error. – Christopher DuBois Aug 17 '11 at 08:55
  • In setups controller, `new` action (or create filter before `new` action) something like that: this.user = getUser(req.params['user_id']) – Anatoliy Aug 17 '11 at 09:08
  • Or, siply, you can pass user_id as param to user_setups helper: path_to.users_setups(request.params['user_id']); – Anatoliy Aug 17 '11 at 09:11
  • Could you append your answer with examples of where to make these changes within setup's controller? (And do you mean loadUser rather than getUser?) Thanks! – Christopher DuBois Aug 17 '11 at 14:28
  • For example, how do change index.ejs? Right now the action urls are empty after trying: <%- link_to('Edit', path_to.edit_user_setup(setup)) %>. I also tried <%- link_to('Edit', path_to.edit_user_setup(user,setup)) %>. I am a bit confused on how to pass user and setup objects to the views and what path_to functions exist (and what arguments they take). Where are these located? (Sorry for newbie questions!) – Christopher DuBois Aug 17 '11 at 15:00