navbars are important
Real talk: navbars are fantastic. They’re really good at their job, which is providing a constant set of routes to your users to find their way around. No user ever gets lost when there’s a good navbar around to help out.
New Rails projects ship with an application layout (that is,
application.html.erb file) that provides an ideal home for our navbar since we want the bar to always be visible at the top of our app, and the application layour is rendered by all views by default.
The problem with navbars is that they typically aren’t very intelligent. For example, when you’re currently viewing a webpage within an application, most of the time the navigation bar does not update to hide that option dynamically. Why, oh why, would you want to click the same link twice? If you feel me on this one, keep reading…
how to make your navigation bars dynamic
I set out to make my navigation bar dynamic (meaning, again, that it would update its contents/links based on which view page the user was currently looking at), and found it was actually pretty straightforward thanks to inheritance in Ruby.
the problem, in words
Abstractly, the goal is to create some object that’s available throughout my application, in all my controllers and views, that will contain the logic and knowledge of the last URL that the user requested. This way, if a user has just clicked, say, “About” on your navigation bar, the next view should not continue to show that link since it’s become redundant.
the solution, in words
I know that every request hitting my application generates a new instance of the controller behind that particular endpoint. I also know that all of my controllers inherit from a master controller of sorts, which is typically
ApplicationController in Rails. Therefore, since my other controllers - the ones actually doing the work of passing data between my models and views - inherit directly from
ApplicationController, I figured I could write a method there that did some introspection on the most recent
ActionDispatch::Request object in order to keep track of the last request’s URL. In code, this strategy looked something like this:
1 2 3 4 5 6 7 8 9
So easy! Through this code, I now had access to the
@current_path variable that would be available at each point in time within my views. Here is how I made use of that object (which is available via the
set_current_path method) in my views in my application layout file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
Now, my navigation bar updates dynamically, presenting the user only with logical options for their next to-be-viewed page or resource in my application. Fantastic!