How to handle non-root urls in one app?

I am trying to create a one-page application with Rails 3.2 and Backbone.js with the pushState option, but running into something that I do not understand.

If I load the root URL of the application (/), everything goes right: Rails returns an HTML layout with JS that loads Backbone, which does some XHR for JSON entities and displays the content.

But if I start using the application from a non-root URL (for example, manually typing it in the address bar of the browser), Rails will try to process this request using its routing rules with route.rb - this is wrong, the Main route. How to load the page and the boot base to process this URL in this case?

+6
source share
3 answers

Finally, I found a solution.

I put the following code in my routes. rb

class XHRConstraint def matches?(request) !request.xhr? && !(request.url =~ /\.json$/ && ::Rails.env == 'development') end end match '(*url)' => 'home#index', :constraints => XHRConstraint.new 

With this match, all non-XHR requests are redirected to the HomeController, which returns an HTML page. And XHR requests will be handled by other controllers that return JSON responses. I also left requests ending in ".json" as valid in the development environment for debugging.

+14
source

This is a somewhat complicated problem, but basically in a nutshell you need to answer all valid (HTML) requests in rails with the same (root) page, from there it will intercept and go to the correct route (in your bakckbone router).

I discussed this issue in more detail here: rails and trunk networks together

Basically, I create actions for every page I want to process, and empty views. I use respond_with to return the page (which is the same in every case), and since I only handle GET actions for HTML requests, I add this line at the top of the controller:

 respond_to :html, :only => [ :show, :new ] 

JSON requests are also processed using respond_with , but unlike HTML requests, they actually return the requested resource (and perform the requested action in the case of PUT , POST and DELETE ).

+1
source

The backbone will not be informed of your change of URL if you do it manually. This change will be captured by the browser, and it will do its job by sending a request to the server, as usual.

The same, if you click on a regular link, it will follow its href without specifying a baseline.

If you want Backbone to be responsible for changing the URL, you need to do this using the basic tools available to you, and this is your own router.

So, if you want to change the URL in Backbone mode, you need to do it explicitly, for example:

 app.router.navigate("my/route", {trigger: true}); 
+1
source

Source: https://habr.com/ru/post/923521/


All Articles