Design Your Queries Like A Boss

As I often repeat the same advice on questions like "What to put in Propel Queries?", or "How to name things?", I decided to share it here.

When you design a software, it's important to use appropriate names for each part, each class, and even each method. In Propel, the ActiveQuery API is probably the most powerful part of your Model, that's why you should take care of it.

First, you should use objects, and forget SQL. If you try to write Propel Queries like SQL queries, you are on the wrong path. A few months ago, someone complained about Propel queries on Twitter because he couldn't write a query. Here is my advice, and his answer:

That's exactly the point! Propel is an ORM you probably use in an OO framework, so why do you want to use SQL, or another query language?

Once you are aware of that, you'll be able to write queries offering the same advantages as objects: encapsulation, reusability, expressivity. The next step is to understand filters. Filters are reusable methods which add conditions to a query. In a Propel Query, you have generated filters like filterById(), filterByUser(), etc. which allow you to write nice queries:

Custom filters have to follow the same convention. You can also wrap filter methods in methods with names that make sense:

You should always name this kind of methods by describing a use case ; that's how you'll get a clean API. Methods in a Propel Query should always return $this to make the API fluent, and you should never add a termination method (find(), count(), etc.). It's the controller's responsability to determine which termination method is needed.

The last advice is about hub methods. Since a combination of filters can be a bit too long in a controller's action, you should write hub methods that combine filters to answer a specific use case. That way, a controller just needs to call this method, it's explicit, and short :)

You now have all keys to write awesome Propel Queries!

Posted by William DURAND 

2 comments

Feb 13, 2012
Daniel Richter said...
Nice writeup, but one thing bothers me a bit, same as with Francois' examples from back then..
On the one hand the auto-generated methods look like "filterByXXX", which is nicely explicit. On the other hand you and Francois (and probably others) pick names like "between", "recent", "cheap", etc.. which is not explicit and doesn't fit the naming scheme. For example, "between" what? I would name the method "filterByReleaseDateRange($begin, $end)". So, just curious if I'm the only one who feels that way..
Feb 13, 2012
William DURAND said...
It's up to you Daniel ;) Let's say if your model class is "Movie", recent() makes sense, it depends on the context.

Leave a comment...