In Progress
Unit 1, Lesson 1
In Progress

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

Today I'm excited to bring you a guest episode from Justin Searls, co-founder of the software agency Test Double, and a frequent conference speaker on Ruby and Rails topics.

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]


Table Print

Justin Searls

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 rdb, byebug, or the console—suppose you can't even call puts! It'd take a lot longer to figure out the bug! That's what developers mean by feedback: it's literally whatever information they glean from the computer to understand what to do next.

Suppose we suspect the bug resides in this method  
If we solicited feedback from the system by using puts, our feedback loop would entail:
  1. Opening our editor to the source listing  
  2. Navigating to the method
  3. Typing puts and the data we want to print  
  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 byebug or pry.
Byebug is helpful for understanding the behavior of the system's execution by enabling us to step through our code's flow-controls
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 _data_, let's try this gem called table_print, which leverages an awareness of ActiveRecord to allow us to quickly build tables of results as we query our data  
When required, table_print adds a top-level method called `tp`. Let's try passing an Arel relation of all of our system's Tag models  
Because table_print takes an ActiveRelation, we can constrain the results just like we would with any query, so let's limit the number of records we get back to 30 rows  
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 table_print lets you define columns as string expressions that navigate your models' associations.
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 table_print.  Let's go one step further and print out the names of the tags associate  d with each individual post
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 table_print's simple API is so expressive that—if you make it a production dependency—you can even prototype basic report pages by capturing its output and rendering it into an HTML <pre> tag.

To accomplish this, we instantiate a Printer object and invoke its table_print method so we get a string back instead of printing to standard out

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 table_print report, we can quickly see that we've replicated the reported bug,  
...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 ``, 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 ActiveRecord model attributes with argument names, or perhaps to consider implementing application logic like this outside of my model classes entirely.  
In conclusion, my hope is you'll find table_print to be worth carrying in your toolbox, and let it serve as an example that no form of feedback is one-size-fits-all. We can get feedback from our systems in many forms, and table_print is a useful one for exploring and visualizing the data in our Rails applications.