How to map non-REST URLS to REST ones? - ruby-on-rails

I have a small rails app that has default scaffold generated routes eg. /stadia/1.xml. However I have to support legacy client app that can't construct such URLs correctly. What I need to do is to map URL in the form:
/stadia?id=1?format=xml to /stadia/1.xml
Or even something like:
/myApp?model=<model_name>?id=<id>?format=xml to /<model_name/<id>.xml
Is it possible to craft appropriate route in Rails?

I don't have good answer for this. What I would do is change first part of url to /stadia_legacy for legacy urls or change first part of urls for RESTful routes.
Then you can map in routes:
map.stadia_legacy :stadia_legacy, :controller => 'stadias', :action => 'please_redirect_me'
Then in stadias controller in action please_redirect_me you can check all params (they are availble in params hash: params[:id], params[:format] etc.) and redirect to correct url. Or you can write all routes manualy to correct controller and action.

What if you do some url rewrite in apache ?

I had a similar question. No answers so far, so it seems routes.rb config doesn't offer an easy way of doing this (routing based on query parameters), which I find surprising actually.
So an ugly workaround would be to have a 'myApp' default route, and then have a special redirecting controller which would look at the query params (because in controllers you do have access to that) and redirect accordingly.

Related

How to get url segment params from a given url outside of a controller in Rails?

Given a path such as
/foos/123
and a route
get '/foos/:id', as: 'foos'
How to get the ID using Rails routes (reverse) look up?
In this example, path.split('/').last would work, and a regex would be better. But how to use the Rails routes to do it?
This functionality was provided by Rails.application.routes.recognize_path but has been deprecated.
Note: This not part of a controller. Please do not answer about how to use routes within a controller.
Rails 6.
You can't. Routing is actually a lot more complicated than that.
The routes are not just a simple static set of regexes that match a string to a controller and action. You need an entire request object. You have to remember that constraints put things like headers, cookies and even middleware like Warden in the picture.
Rails.application.routes.recognize_path was depreciated since it completely failed at handling this complexity. It just gave a false sense of simplicity which is probably the worst thing software can do.

Ruby on Rails database driven router to support fully customizable urls

I'm planning to port our current cms (written in PHP) to Rails. All parts do well, except for one: routing.
Like most cms systems, the routing in our cms based on a database with pages, which are linked to modules, controllers and actions. On this approach a user can fully customize or specify it's own urls.
I know that Rails (and most (application) frameworks have the approach of defining routes in a file, but I hope this is possible.
The approach our users should have is:
add new page
select type (news, form, product, ...)
select an item (select which form, blog or product should be displayed)
enter a url for that page
Special the last point (4) is important. A user should be able to add form A to /contact-us, and form B to /clients/register-as-new-client e.g.
On a request the router needs to do a database query with the page url, to find out which controller, task and parameters should be dispatched.
Question has been updated, and i don't think this is a valid answer anymore
we have a similar paging system. we use a routing glob. in routes.rb:
get 'pages/*lookup_path', to: 'pages#show', defaults: { format: 'html' }, as: 'page'
Just parse params[:lookup_path] in PagesController to suit your needs
'http://localhost/pages/users/'
params[:lookup_path] #=> users/
'http://localhost/pages/users/23'
params[:lookup_path] #=> users/23
'http://localhost/pages/people/1'
params[:lookup_path] #=> people/1
Although this solution isn't ReSTful, I think this should solve the issue.
Regardless, Rails uses routes in a file. You cannot change this since the framework heralds "convention over configiuration". All I can do is point you in a direction to minimize this.
There is a catchall route in Rails (on RailsCasts, and on StackOverflow) which you can use to direct all routing to one controller action. You may further customize the routing behaviour in that method
You could also make a route like…
:controller/:action => Controller::Action
…as is done in CodeIgniter, but now your methods have to have names like contact-us and register-as-a-new-client.

Resolve Route Server Side in Rails

Just as you figure out the route when the browser hits the webpage in Rails, how would you resolve it on the server side?
For example I want to return a URL to a RESTful resource called Bookmark in an API call and want to return the 'show' action of it, and I know that:
Bookmark id: 12
Then I want to resolve it to a string:
'/bookmarks/edit/12'
so that I can get this from my Model for example.
How would I go about doing this?
Thanks!
Pretty much everywhere in the views/controllers you can use route helpers to DRY up route references.
In models, you'll need to explicitly call the route helper like so.
Rails.application.routes.url_helpers.edit_bookmark_path(id) # => '/bookmarks/12/edit'
When using the default resourceful route generator method in routes.rb like
resource :bookmarks
I'm not sure I understand - your server is the thing that's making all of those routes work - the client's browser isn't figuring out what the route is - you application is doing it.
The paths to your resources are available as helper methods at all times (at least within the controllers, and views). As such, you should return the string as the body of a response in one of your actions, in the controller that's handling your API calls.
Check your rake routes on the command line, and you'll see a list of them. In the case of your example above, it would likely be called edit_bookmark_path(12)

Rails way of constructing & redirecting to an url with post parameters of a form

I would like to do that's the best way of actually accomplishing the
following on Rails.
I have a "Booking Form" with 5 fields (Property, Amount of Children,
Amount of Adults and 2 Dates - Departure and Arrival) based on these
fields, I need to construct an URL and redirect the user to this url.
Now, I have 2 questions.
1) How i catch the POST parameters in the controller, because I'm
mapping the form to an action like this:
<% form_tag(:action => "booking") do %>
and routing it to a controller action like this: (Pages Controller,
Booking Action)
match 'pages/booking' => 'pages#booking'
2) Is this the Rails way of actually accomplishing such thing?
I did it this way in PHP in the past, but now I have the need of
actually doing it in Rails, could you Rails Gurus inspire me ?
To access parameters in the controller, even ones submitted in a POST body, use the params hash. Eg: params[:form_field]
To redirect to another URL using a controller, use redirect_to. You can certainly use the values in params to construct a URL and pass it to redirect_to.
If you're using resourceful routes, which is the best way to go about such things, you would route things through the traditional approach:
resources :bookings
Then you'd post the form to bookings_path and it would all work out, as that's BookingsController#create. It's always better to have a strong correlation between model and controller where possible.
The resources definition in routes.rb helps you by creating all the default RESTful actions which you can build off of. If you really need a custom route, you can always rename it using the :as option, or route it independently.
If you go about creating your own arbitrary routes, such as /pages/booking you're going to create quite a mess that someone else will have to maintain. Quite often that someone else is you in the future.

Rails 2 Trailing Route Parameter

I'm building an article/blog website where any article may show up within a series of URL paths.
/section/article
/section/page/article
/section/page/page2/article
This works, but what if I wanted to have the page number for that article (/page/123) be bound to those URLs
/section/article/page/123/
/section/page/article/page/123
/section/page/page2/article/page/123
This would mean that I would have to create a specific route for each different url?
/:section/:page/:sub_page/:article/page/:page
This would mean that I would create dozens of URL routing paramters.
Is there anyway in rails to say that all urls may have a /page/NUMBER suffix at the end of the URL and still route normally (that is assign the NUMBER to a parameter and continue to goto the page normally)?
Route globbing, described at http://guides.rubyonrails.org/routing.html#route-globbing, might work in this situation. For example, your route might read map.connect '/:section/*page_subpage_path/page/:number', :controller => 'articles', :action => 'show'
This exact code might not work as intended, but this method might be a good direction to try. Good luck :)
If you want to create routes that are as customized as that you normally need to create a large number of routes to accommodate them. The general format is /resource/:id when using map.resource, anything other than that is left to you to specify.
Given that the Rails routes.rb file is executable ruby you can often define your routes programmatically by repeating patterns or doing combinations on arrays if required.

Resources