Passing parameters with RESTful urls

Hi,

I'm using RESTful urls for a person model, such as edit_person_path and new_person_path. The problem I am having is that I want to pass some parameters with some of these urls: I want to pass the current person id to the new person_url, as the new person is to be a child of the current person. I keep getting an error when I try new_person_path(@person.id)

Is this because it is not a POST request?

I would also like to set an instance variable in the new action @person_id = @person.id

I want this to then be passed with the form to the create action. In the form, I am using the new Rails 2.x syntax: % form_for @person do |f| %>

In the past I used: <% form_for(:person, :url => create_person_path(:person_id => @person_id)) do |f| %>

How would I first of all make this variable available to the new action and then pass it on to the create action?

thanks,

DAZ

when I try new_person_path(@person.id)

if you use additional parameters you must give them names like:

new_person_path(:person_id => @person.id)

to hand additional parameters with forms i would use a hidden_field

Thanks Thorsten,

I can now pass an extra parameter with my new_person_path.

I could now use a hidden form field, as suggested, but in the past, I have simply been able to pass extra parameters through the form_for tag like so:

<% form_for(:person, :url => create_person_path(:person_id => @person_id)) do |f| %>

Is there anyway I can still do this as it would be preferable to using a hidden form field?

I've tried:

<% form_for @person, :person_id => @person_id do |f| %>

but it doesn't work. It seems that I am simply trying to do the same thing as I did with the new_page path. Unfortunately there is now a bit of 'rails magic' going on in the background. It is making it a 'put' request because it is in the 'new' view. How do I add extra parameters to these 'magic' form_fors?

DAZ

I believe this should work:

form_for :person, :url=>people_path(:person_id=>@person_id), :method=>:post

This was the actual code that worked (it needed the singular person_path rather than the plural people_path, and this required a parameter of @person):

<% form_for @person, :url=>person_path(@person, :person_id => @person_id),:html => { :method => :post } do |f| %>

Thanks for all the help everybody,

DAZ

DAZ,

Are you using acts_as_tree for this?

acts_as_tree allows you to define parent_id, rather than people_id, and then defines methods on your objects like #children to see all the children of a certain object.

Hi Ryan,

I'm actually using the betternestedset plugin. This has the same methods as acts_as_tree, I'm over-riding the column name parent_id with people_id, so it still works.

The difference with this plugin is that you can't just do Person(1).children.new, you need to create a new peson, then move it to be a child of a certain person. This means that the parent's id needs to be continually passed through the new and create process (as far as I can see.....)

The method I mentioned above is the best way I could find of doing this. Have you got any alternatives?

cheers,

DAZ

But will this nested route work recursively? What if I wanted to do

Abraham is a parent of homer who is a parent of Bart, could I do:

parents/abraham/children/homer/children/new ???

I like the sound of using nested RESTful routes and will have a look at them. Could I nested routes with the same name, ie: map.resources :people do |parent| parent.resources :people end

It would also be good if I could get rid of having to put 'people' in front of all the urls, so I could just use paths like: people/abraham/homer/bart

This way, the url shows the family tree...

Thanks again Ryan,

DAZ

No you can’t do that unfortunately. I think with your plugin you should already have a method to get the ancestors of a perosn.

cheers Ryan - yest I've used the Person.ancestors method to then create a path that can be used to create an url that looks like a family tree. This involved over-riding the RESTful urls using:

map.family-tree '*family', :controller => 'people', :action => 'show'

This gives you an array called 'family' with the whole family tree and works quite nicely!

DAZ