Filter Out Unnecessary Recursive Relationships
Add a small function to your AppModel to filter out those recursive relationships that are unnecessary for a particular controller action.
I wrote this using the following articles for references. Thanks folks, they helped me write this snippet in about 15 minutes.
unbindAll by cornernote Keeping bindModel and unbindModel out of your Controllers by TommyO An improvement to unbindModel on model side by mariano
I didn't need the full functionality of some of these solutions. I just needed a way to quickly and succinctly filter out a particular model's associations.
Please comment with your observations, corrections, and/or comments.
Add this function to your AppModel:
Then in your controller use the 'filterBindings' function:
unbindAll by cornernote Keeping bindModel and unbindModel out of your Controllers by TommyO An improvement to unbindModel on model side by mariano
I didn't need the full functionality of some of these solutions. I just needed a way to quickly and succinctly filter out a particular model's associations.
Please comment with your observations, corrections, and/or comments.
Add this function to your AppModel:
Model Class:
Download code
<?php
class AppModel extends Model{
/**
* Performs an 'unbindModel' on an array of associations
*
* @param array $bindings An array of model associations to unbind from current model
* @return null
*/
function filterBindings($bindings = null) {
if (empty($bindings) && !is_array($bindings)) {
return false;
}
$relations = array('hasOne', 'hasMany', 'belongsTo', 'hasAndBelongsToMany');
$unbind = array();
foreach ($bindings as $binding) {
foreach ($relations as $relation) {
if (isset($this->$relation)) {
$currentRelation = $this->$relation;
if (isset($currentRelation) && isset($currentRelation[$binding])) {
$unbind[$relation][] = $binding;
}
}
}
}
if (!empty($unbind)) {
$this->unbindModel($unbind);
}
}
}
?>
Then in your controller use the 'filterBindings' function:
Controller Class:
Download code
<?php
class PostsController extends AppController {
var $name = 'Posts';
function index() {
$this->Post->recursive = 2;
$this->Post->filterBindings(array('Comment', 'Rating'));
$this->Post->User->filterBindings(array('Status'));
}
}
?>
Comments
Comment
1 How is this easier than Bindable behavior
For example, what if your Post model changes? You would have to go back through all your code to find filterBindings() and re-write them to include any changes in Post's relationships.
Using Bindable behavior, you INclude all the models you need, rather than EXcluding them. Plus, you can do neat things like query based on HABTM conditions, select only certain fields from related models, and much more.
Plus, it sets the level of $recursive AND returns the value when you make a call to restrict().
I would suggest looking into Bindable if the above solution is too limited for your needs.
Comment
2 This is for version 1.1.x