Table Print with Justin Searls
If you’re not already using
table_print to debug problems in your Rails applications, you’re probably losing valuable time to tedious data exploration. Join guest chef Justin Searls for a lightning course in using this tool to quickly visualize complex app data sets. Along the way, you’ll learn about how investing time in tightening your feedback loops is one of the best ways to optimize your development process.
Video transcript & code
On the surface of it, today's episode is about a handy Rubygem for exploring and displaying the data in your application. But the underlying topic is something deeper and much more important: it's about feedback loops. Today Justin shows us how investing some time and a little creativity into tightening our development feedback loops can pay big dividends for our overall productivity.
[su_box title="Editor's Note --- from the RubyTapas Masala Chef" box_color="#283037"]In keeping with the spirit of this episode, the script is presented in tabular form.[/su_box]
|You may have heard experienced developers use the term "feedback loops" to describe the speed and quality of tests, log messages, print statements, and so on. But what does feedback mean and why does it matter?|
|Well, imagine you have a large Rails blogging app, and you just received a bug report that tags are being attributed to the wrong author.
Now imagine you lack access to
|Suppose we suspect the bug resides in this method|
|If we solicited feedback from the system by using
|1. Opening our editor to the source listing|
|2. Navigating to the method|
| 3. Typing
|4. Exercising the code that triggers the suspected code path|
|5. Hunt through the console to find the log message|
|6. Realize the bug isn't materializing in this case|
|7. And starting the whole process over|
|Debugging with puts could take all day! That's why people more often break execution to get faster feedback with tools like
|Meanwhile pry is great for understanding the state of the system's object model—what messages an object can respond to and so on|
|But what if the feedback we need is about the state of our application's persisted data? Whether we're using a debugger or pry, the best we can do is print page after page of models. Neither tool is well-suited to answering this kind of question|
|For fast feedback to questions about the state of our system's
|When required, table_print adds a top-level method called `tp`. Let's try passing an
|And because table_print will display every column by default, we can narrow which columns to print with additional arguments after the relation|
|Let's print the tags again, this time only looking at the tag name and the author who created the tag|
|Did you notice how the author column changed from displaying a numeric ID to a Ruby object? That's a hint that
|So let's make the author column more readable by changing the symbol to a string and asking for its name property|
|There, that's much better. — But where table_print really shines is in how it handles even more complex associations|
|This time, let's try table printing our authors, with columns for their e-mail addresses and the titles of the posts they've written|
|Look how well table_print handles this! It printed each author once, but created a separate line for each of their posts. Here we can easily see that Jack has 2 posts and Jill has 3.|
|We can drill even deeper into our model's associations when visualizing our data with
|Notice how our resulting table fans out even further to list each of the tags owned by each post.
Just like ActiveRecord spares us having to think about SQL JOIN syntax, table_print allows us to express ourselves in terms of simple association names, handling things like 1-to-many relationships for us.
|In fact, I've found that
To accomplish this, we instantiate a Printer object and invoke its
|It's not especially pretty, but it's a lightweight way to demonstrate what a report might look like before investing in proper markup and styling.
|So not only can table_print get you fast feedback when troubleshooting problems with your data, it may be able to help you iterate on feature work more quickly, too.|
|But first, let's think back to the bug about tags being misattributed that started us down this path. At first, we tried to replicate the bug by tagging one of the posts written by the author Jack, and it seemed to attribute the tag to him correctly.|
|This time, let's try creating a tag on the same post, but attribute it to a different author, in this case, Jill|
|Going back to our
|...and that the new tag was erroneously attributed to Jack.|
|When we revisit the affected method, we know our actions in the browser would have instantiated a new Tag model, so we can hone in on that particular code branch|
|That added focus will make it easier to spot our bug: we're assigning `author` to `self.author`, which is actually the author of the post, not the author argument passed in to the method. To fix this, we just need to reference the argument instead of the attribute.|
|One might hope this would teach me not to shadow
|In conclusion, my hope is you'll find