Blog: 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 because you're too close to a SQL mind, try to think with an object oriented mind :)
— William DURAND (@couac) October 9, 2011
@couac m.. yes, thinking about "traversing across object relations" instead of "let's retrieve data" may help when doing complex queries.thx
— Nacho Martín (@nacmartin) October 9, 2011
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!