Monday, August 1, 2011

Keeping your Yii Models Lean - Use Behaviors

Active Record models are fantastic for consolidating "black box" logic and keeping your models self-aware of their business logic, but what do you do when the business rules and object specific operations keep adding up?

Do yourself a favor, and get into the habit of putting those business logic methods into attachable behaviors.


If you're not familiar with Behaviors at all, you can catch the basics here:
http://www.yiiframework.com/doc/api/1.1/CBehavior
http://www.yiiframework.com/doc/api/1.1/CActiveRecordBehavior

Not only does it make it easier to maintain your code, but it makes it much easier for a team to collaborate within the same area of development. You'll also end up with a nice library of components which you can reuse.

For example, there is the built in timestamp behavior for updating timestamp fields on CActiveRecord models. See: http://www.yiiframework.com/doc/api/1.1/CTimestampBehavior/


Need to ensure that some special logging happens each time a model is saved? Create a CActiveRecordBehavior for the model that has an afterSave method defined to run your checks and fire off the required logs/emails/what have you. You can use the same behavior for multiple models, so that if the logic needs to change, you can easily do so by changing just the behavior and not touch your core models.

Even if the logical process only applies to the one model, it's worth putting it into a behavior just so that you can adjust the business end of it without modifying the core model.

For example, if you have a 'Blog' model that requires approval before it can be publicly visible, it makes sense to put the 'approve' method, right on the model so that you can access it consistently from multiple controller actions/etc. But even better, is to make that approve method a behavior that is attached to the model, along with the 'reject', etc. methods. Then, if you need to regenerate your core model for some reason (yii upgrade perhaps??) you can do so without losing your business logic pieces and conversely, if you need to update the approval process in some way, you can do so without the potential of breaking your blog model or have one person developing the approval process while another person works on the validation routines, etc. without conflict.

This is especially important when you have very complex rules that need to be applied to a model consistently regardless of where it is accessed from, so it's a good habit to get into early.

One of the rules of thumb for this is, if you find yourself adding extra properties to the model to track information related to some business process, it's a good bet you should be making that a behavior.