Active Record queries in views: when it’s bad, when it’s fine

By Jason Swett, March 3, 2021

Maybe you’ve heard the advice that you shouldn’t put Active Record queries (or other logic) in views, but you’re not sure exactly why, other than “separation of concerns”. Why exactly is separation of concerns good?

The rationale behind this advice is that mixing concerns (like query logic vs. presentation) makes the code harder to understand and change.

Another way to think about this is to think about what kinds of things tend to change together.

Related changes

Even though many changes require touches at multiple levels in order for the change to be complete (model, controller, view)​, some changes are more closely related than others.

A change to the SQL in a query is more likely to call for other SQL changes than it is to call for a CSS change. For this reason, it usually makes sense to put query code next to other query code so that all the query code can be noticed and considered and worked with at the same time.

Sometimes queries in views is fine

Having said that, I don’t dogmatically follow a rule of “no queries in views”. If I for example have a select input and it needs to contain all categories, I’ll unashamedly put Category.all right into my view code. The alternative to this is to clutter up my controller with instance variables and before_actions.

The reason I don’t feel bad about this is that Category.all is unlikely to ever influence or be influenced by some other model change. And in the unlikely event that I’m wrong about that, I can easily move that query out of the view when I need to. But I’m hardly ever wrong about that. (I never put complex queries in my views though.)

Takeaway

Keeping logic code out of views tends to help make your code easier to change and understand. It’s generally good to keep Active Record queries out of views, but putting Active Record queries in views is typically harmless when the query is very unlikely to influence or be influenced by anything else.