Last lecture, we covered Rails. Our instructor, Avi, mentioned how the level of abstraction with which Rails operates can be a double-edged sword. On one hand, it provides concision and expedition, as it neatly tucks away its complex inner workings in the Rails source code. The end result is a mode of programming that seems almost magical, as Rails’ conventions somehow so mysteriously connect the dots for you.
Conversely, its “magic” is what makes it all too easy for people to use Rails without knowledge of what goes on underneath its hood. This can be problematic, as you can run into trouble the moment you decide to write against its fixed conventions.
So that we ourselves would not become victims of this issue, Avi walked us through a few examples. Notably, he broke down how Rails abstracts the insertion of dynamic URL strings into its ERB files. So that it mentally sticks, I’ve decided to write a play-by-play, peeling away the layers of abstraction.
Let’s imagine that I’m building an index page in ERB, where I list out links for each frog in my database, and let’s say that there’s code that looks like this:
On the first line, an instance variable defined in the corresponding controller,
@frogs, embodies an array of ActiveRecord objects through which we iterate. On the second, we call upon the
.id method for each instance of frog at the end of the path within the
<a> tag, thus constructing a different link for every instance. The word “Show” represents the URL display.
So, this is how one might generate dynamic URLs via classic ERB. But let’s refactor this using some DHH magic.
The Rails Way to ERB
In Rails, we can write the second line differently––a bit more clean, like this:
link_to method replaces the
<a> tag. The first argument,
Show, produces the link display. While this is straightforward enough, we see a multi-layer level of abstraction in the second half of the argument,
frog, which summons an implicit method that Rails creates using the
frog_path. Concretely, it can be written as such:
frog_path calls a prefix corresponding to a URI pattern, as defined via
config/routes.rb. We’ll see that in our example, it maps to a “get” request to the URI pattern of:
The argument passed through
frog_path is piped into the URI pattern where the
:id resides. Yet, the argument itself,
frog is not what you might immediately think.
Let’s back up a bit.
frog is an ActiveRecord Object, which has the following output:
Understanding this, one would suspect that
frog in the example above abstractly calls upon
frog.id. But it’s a bit more complex. There’s actually an implicit method
to_params attached to the Object:
In ActiveRecord::Base, the
to_params method is defined:
Now, while the above is its default behavior, one can still overwrite the method to call something other than
self.id (e.g. an object’s slug). You can do it this way:
Or further abstractly:
However, as was noted in lecture, this would open up much possibility for conflict, and would require more work on the developer’s part to ensure consistency––especially in instances with hundreds of links to consider. One can instead change the implicit call to
to_params at its source by going into the
Frog class, and overwriting the method definition there: