1

I'm still trying to get the hang of rails and i'm trying to create a simple app with a form where i can enter the data and then submit it and it will be stored in the db. I got this very simple by starting a new project and then running:

$ rails generate scaffold RSVP firstName:string lastName:string

Now i want to redirect to a thank you page after adding a new record via the form.

I've manually added the method below to my rsvps_controller.rb file:

# GET /rsvps/thank_you
  def thank_you
    respond_to do |format|
      format.html # thank_you.html.erb
      format.json { render json: @rsvps }
    end
  end

This line is in my routes file:

resources :rsvps 

My question is, when i run rake routes, i don't see a route for my thank_you method. Shouldn't my :rsvps resource pick up my thank_you route and how does the routes know which controller method are which http calls(get, post, put, etc)?

5 Answers 5

6

In order to get a route that will hit that action in your controller you should have in your routes.rb file something like:

resources :rsvps do
  member { get :thank_you }
end

or

resources :rsvps do
  collection { get :thank_you }
end

it depends for if you want to access the resource you've just created or not.

You can take a look @ http://guides.rubyonrails.org/routing.html it should help you understating the routing mechanism better.

Sign up to request clarification or add additional context in comments.

2 Comments

When i use the member line that you suggested, i see this line in my rake:routes: thank_you_rsvp GET /rsvps/:id/thank_you(.:format) rsvps#thank_you. Why does it expect :id in the path?
The member method in a resource route means, "these will be used in relation to an individual record". So the ID is necessary in order to find the record. If you don't want an ID, (that is, you want it to apply to "all records in the controller", or you otherwise want it to be unrelated to individual records), then you should use collection per the second example. To clarify, using member, the :id will be passed into params[:id] within the controller method itself. It's the difference between acting on a single rsvp, or acting on all or none of them.
3

Adding on to what wlad said, the resources :rsvps things in your routes.rb file creates a set of default routes that are going to be needed by most models. Things like index, new, create, or show. The reason your thank_you action isn't showing up in rake routes is because thank_you isn't one of the actions that were so common that they needed to be included out of the box without extra code.

1 Comment

Those are called RESTful routes, and unless you have a good reason not to, you should stick with them. Especially if you are just in the beginning stages. Get your app working, then, as a finalization development task, you can customize the URLs. And note, one of the most awesome things about rails routing is the route helpers. I won't bore you with the details, but keep them in mind if/when customizing URLs.
2

If you are going to need to load a rsvp model on the thank you page to display any data in that model then you will need to use a member route. The :id in the route will be there because this is a resources member route and has to be associated with a particular resource. There has to be something in the url to know what to load.

resources :rsvps do
  member { get :thank_you } #GET /rsvps/:id/thank_you(.:format)
end

If you just want a generic route that points to that controller action then you can use something like this:

match "/rsvps/thank_you" => "rsvps#thank_you", as: "rsvp_thank_you"

Comments

2
+50

You can add more actions to any controller but rails will not treat this functions as actions unless you specify them in routes file. It will be treated as just another function in controller class created by user.

so if you want to add the thank_you function as action you need to add this to routes file.

There are multiple ways of doing so as others have explained in their answers.

  • adding-more-restful-actions

    Using member and collection inside resources.

    Use member when you want the function to be used only with the some model object. eg: preview for photo id 1
    GET /photos/:id/preview

    In our example you member if you want such route and functionality.

    GET /rsvps/:id/thank_you

    Note :id in params is needed when you specify it as a member action.

    resources :rsvps do
      member do 
        get :thank_you  #GET /rsvps/:id/thank_you(.:format)
      end
    end
    

    Use collection if you want to call the action directly like

    GET /rsvps/thank_you(.:format)

    in resources

    resources :rsvps do
      collection do 
          get :thank_you  #GET /rsvps/thank_you(.:format)
      end
    end
    

    You need to specify the type of action (GET|POST) while adding it to routes.

    In our example thank_you has been specified as a GET action. You can choose either.

You can create you own preety_urls or non restful routes using match. (This will also require to have the action defined in resources block).

check out more on match here http://guides.rubyonrails.org/routing.html#non-resourceful-routes

I suggest you to go through this awesome documentation created by the rails team.(once more ;) ) http://guides.rubyonrails.org/routing.html

Cheers.

2 Comments

Thanks for the awesome answer. I've read/skimmed through the routing guide a couple of times. There's a lot of information there so it's quite daunting.
Also - isn't it also possible to do something like this get '/rsvps/thank_you', :to => 'rsvps#thank_you'? This doesn't work, but i thought i'd be able to do something similar.
0

As you have said you just want to show a thank you page for each rsvp so a member route should be used. like this

resources :rsvps do  
  member get :thank_you
end

You should use collection of thank_you when you want to show all or some specific collection of thank_you.

when you include this and run rake routes again you will see the new http action there.

1 Comment

When i use your code i get the error wrong number of arguments (1 for 0)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.