Rails implement an API using Routes pointing to existing controller actions - ruby-on-rails

I have a Rails app that does everything I need it to do via a HTML interface, now I'd like to bolt on an API providing access to bits of the functionality.
How would I do this selective forwarding of some API controller actions to another controller's actions using the Routes.rb?
I have tried the following:
My regular controller routes work fine using:
match 'stuff' => 'stuff#index'
get 'stuff/index'
get 'stuff/some_get_action'
post 'stuff/some_post_action'
But then when I try for my API:
match 'api' => 'api#index'
match 'api/some_get_action' => 'stuff#some_get_action', :via => :get
match 'api/some_post_action' => 'stuff#some_post_action', :via => :post
or...
match 'api' => 'api#index'
get 'api/some_get_action', :to => 'stuff#some_get_action'
post 'api/some_post_action', :to => 'stuff#some_post_action'
I get an error. When I navigate to /api/index to server a HTML page that contains forms for testing the API URLs the url_for raises a 'Routing error' exception saying 'No route matches...'.

You may want to include ':as => ' and define your route names that you may be using as your link paths.
get 'api/some_get_action' => 'stuff#some_get_action', :as => 'some_get_action'
and the link path in your index file will have 'some_get_action_path'. Not sure that 'match' or 'get' automatically resolves to a path name, which by setting ':as' it definitely will.
I like your idea for setting up this page for testing. I'm always doing it in the console, which is surely more difficult than simply clicking a link. Your links probably need to infer that they are :json requests, not :http.

Related

Cant rename rails routes

I want to rename a few of my routes, for example:
get 'legal/terms_of_service', :to => 'legal#terms_of_service', :as => :datenschutz
that works, but it doesn't change the acutal URI- and I want that to be changed as well. path: does not work here.
Thank you
If you want the URI to be /datenshutz then you can do this:
get '/datenschutz', :to => 'legal#terms_of_service', :as => :datenschutz
The get '/datenschutz' determines the url browsers or other http clients use to access the controller.
The :to => 'legal#terms_of_service' specifies a controller class and controller action used to respond to the route.
The :as => :datenschutz changes the method you use in views to create links to the route (such as datenschutz_path).

How does redirect work in rails?

I don't have a /charge page. But I do have a subscription/charge page. I was wondering, how do I say, "if a user goes to /charge, redirect them to subscription/charge" using routes
No route matches [POST] "/charged"
You can modify your routes.rb file to point a url to a specific action
get '/charge', to: 'subscription#charge'
I'm using something similar to below in my application for post:
match '/charge' => 'subscription#charge', :via => [:post], :as => :subscription_charge
you can also write:
root 'subscription#charge'
and you'll be redirected to the charge page if accessing http://localhost:3000

Rails 4: You should not use the `match` method in your router without specifying an HTTP method

Okay, so I've upgraded to Rails 4 (kind of unplanned with my 10.9 server update) and have been able to get everything running on my photo gallery app except for the routes. For some reason I've always had trouble understanding routes since rails 3. Here was my previous working code under Rails 3
root :to => "gallery#index", :as => "gallery"
get 'gallery' => 'gallery#index'
resources :galleries
match 'gallery_:id' => 'gallery#show', :as => 'gallery'
I understand that match has been depreciated, but if I try to use GET, I'm getting the following error:
Invalid route name, already in use: 'gallery' You may have defined two routes with the same name using the :as option, or you may be overriding a route already defined by a resource with the same naming.
Basically, I want the root (index) to load as "/photos/gallery" as it does, and my show action to load, for example, record id 435 as: "/photos/gallery_435" which is how I previously had it working. Sorry for what is probably a simple question, I just cannot seem to grasp the rails routing.
Try this
match 'gallery_:id' => 'gallery#show', :via => [:get], :as => 'gallery_show'
You can then refer to this path as gallery_show_path in your helpers and views.
Changing the 'as' removes the conflict.

Custom url in ruby on rails

I know rails uses the controller action style urls like www.myapp.com/home/index for example
I would like to have a url like this on my rails app, www.myapp.com/my_page_here is this possible and if so how would I go about this?
You just use a get outside of any resources or namespace block in your routes.rb file:
get 'my_page_here ', :to => 'home#index'
Assuming you are using Rails 3+, do NOT use match. It can be dangerous, because if a page accepts data from a form, it should take POST requests. match would allow GET requests on an action with side-effects - which is NOT good.
Always use get, put, post or these variants where possible.
To get a path helper, try:
get 'my_page_here ', :to => 'home#index', :as => :my_page
That way, in your views, my_page_path will equal http://{domain}/my_page_here
you just need to make a routing rule to match that url
in this case it will be something like
match 'my_page_here' => 'your_controller#your_action'
your controller and action will specify the behavior of that page
so you could do
match 'my_page_here' => 'home#index'
or
get 'my_page_here', :to => 'home#index'
as suggested in other responses.
for index action in home controller if you have such a controller
see http://guides.rubyonrails.org/routing.html for more details
also see Ruby on Rails Routes - difference between get and match

Rails how to rewrite this old route map.connect?

How do I rewrite this old route Rails 1.2.6 to Rails 3? :
# Allow downloading Web Service WSDL as a file with an extension
# instead of a file named 'wsdl'
map.connect ':controller/service.wsdl', :action => 'wsdl'
I canĀ“t see how I should use match route etc.
I have used:
match ':controller/service.wsdl', :action => 'wsdl'
But I dont think it is working correct
Try this:
match '/controller/service.wsdl' => 'controller#service.wsdl', :as => :wsdl
I'm guessing that your controller is not named controller. If it is, I'd rename it and change the above route as well.
I haven't found a good solution to converting Rails 2 parameterized :controller and :action generic routes to the more explicit Rails 3+ format. What I've had to do is go through every permutation in my app and add an explicit route for everything I needed to support. For example, in your case, if you had 3 controllers that supported the wsdl action, I'd add a new route for each using either match or get.
Here's what it might look like, assuming you had a foo_controller, bar_controller, and a blah_controller that all support the wsdl action:
get '/foo/service.wsdl' :to => 'foo#wsdl'
get '/bar/service.wsdl' :to => 'bar#wsdl'
get '/blah/service.wsdl' :to => 'blah#wsdl'
This gets even more fun when you need to support every action on a controller when they use :action.
If anyone has a better method, I'm open (and eager) to hear of a better way.

Resources