This blog is a continuation of Rails Routes P.1 Understanding Route Structure
A common task when building Rails applications is creating custom routing, so let's look at a few ways we can restructure the anatomy of our routes.rb file.
Changing the URL of a static generated page.
Let's start with the common task of routing static pages, say we generate two pages with;
rails g controller Pages about contact
This command will create a directory appropriately named Pages with two pages named ‘about’ and ‘contact’. However, what will the routes look like, well initially this..
As these pages live in the Pages directory Rails helpfully tries to rout it for us, however, you may see there is a small catch to this. The route for ‘about’ and ‘contact’ is preseeded by pages meaning each URL would start with “/pages” (hostname/pages/about) to visit ‘about’, (hostname/pages/contact) to visit ‘contact’.
However, as you can see in the example above this issue is easily rectified with ‘to:’. We the syntax get ‘about’, to: ‘pages#about’ we instruct Rails to route /about to look in the pages directory and render about, easy as that!
Making a Custom Prefix
In the past, you may have used a rails helper method such as _path it’s, we would proceed this method with a prefix for example contact_path. Like many things in Rails a prefix can be customized too, take a look at the example below.
Here we give with about page a custom prefix of “about_page” we can do this using ‘as:’.
Creating A Route Page
A common task in an application is creating a root (or home page), we can do this in a very similar way to the others with ‘to:’ however this time we use the keyword root.
Creating nested routes
The idea of a nested route is to have multiple pages under the same relational URL. For example, say we have 3 pages named ‘main’, ‘user’, ‘blog’ and we wanted them all under the same relational URL ‘/admin/dashboard/’ (main as ‘/admin/dashboard/main’, user as ‘/admin/dashboard/user’ and blog as ‘/admin/dashboard/blog’). It is here we would use nested routes.
The first step to achieving this is creating a namespace, take a look at the example below.
Here we have created a namespace ‘:admin’ (this represents the relational URL ‘/admin’), following this, we place the relevant pages into a ‘do’ block (these are located in ‘dashboard meaning in this scenario they will be routed under admin/dashboard/). In plain English, we are saying “Under the namespace, ‘admin’ route the following pages”.
Here’s where things get a little funky, in order for this to now work we need to ensure our files are in the correct place. In the example above the ‘main’, ‘user’ and ‘blog’ pages share a controller named ‘dashboard’, however are placing them under the namespace ‘admin’.
What this means is we now need to go to our controller's directory and a new folder within it named ‘admin’ (our namespace). We then place the relevant controller inside it, in my case as previously mentioned it will be the ‘dashboard’ controller.
The same process will also apply to our views, so in the views directory again create a new folder and place the relevant views inside.
Now we have that sorted we need to create a small change to the controller itself to ensure we are pointing it to the right place.
Take a look at the code above just after class I added the namespace ‘Admin’, this will be added with a capital spaced apart from the controller name with two colones.
Now with this final step, the routes should be working, as said it's slightly finicky but it’s a valuable skill to have!
In part one ‘understanding route structure’ I briefly touched on requests such as GET, POST, PATCH, PUT and DELETE. In the context of Rails these methods are typically used to implement CRUD actions (create, read update destroy). In Rails HTTP methods are implemented with ‘resources’ a common implementation can be seen in the example below.
In this example, I have a ‘blog’ model and a blog controller, it is important when we point to a resource we use the specific controller name. In my scenario I have a blogs controller, the correct implementation will be resources :blogs.
For more in-depth guidance visit the Rails resources documentation here.