[eluser]rherriman[/eluser]
I'm having an issue I hope that you can provide some insight on, WanWizard. For reference, we are currently using DM 1.8.1 on CI 2.0.2--they've been a little reluctant to upgrade here at work after those issues introduced in 2.0.3 with protected methods. But I don't think this is related to my problem.
In several of my models now, I've taken to extending the __get magic method in certain cases: when simple $object->relation querying doesn't suffice. For example, we have "categories" (infinitely deep) and "products" that are assigned to them. We also have "media" that we can attach to either categories or products. Now let's say that I want to get a (distinct) list of media for a particular product, as well as the media assigned to its direct parent category. $product->media->get() won't provide that. Ideally, too, that functionality would be part of the model itself. My solution was to do this:
Code:
class Product extends DataMapper {
...
public function __get($name) {
// Prepare the resolved_media property. More than just an alias of
// media, this will also retrieve the UNION of $product->media and
// $product->category->media.
if($name == 'resolved_media') {
$this->{$name} = new Media();
if(!$this->exists()) {
// Ensure an empty result set is returned if this product does
// not exist yet: if it doesn't exist, there are no relations.
// Yes, I know this is kind of... unpleasant.
$this->{$name}->where('id', 0);
} else {
$this->{$name}->distinct();
$this->{$name}->group_start();
$this->{$name}->where_related_product('id', $this->id);
$this->{$name}->or_where_related('category/product', 'id', $this->id);
$this->{$name}->group_end();
}
return $this->{$name};
}
return parent::__get($name);
}
...
}
This works as I had hoped. You can do $product->resolved_media->{other query methods}->get() and end up with the results you would expect. However, it only seems to work correctly once. If you want to run another query on resolved_media, it ignores all of the filtering defined in __get. It does, however, honor method chaining. resolved_media itself just becomes something of a blank slate, no different than if you were running queries on a fresh instance of Media.
This is one of the simpler examples that I have. Ultimately I'm providing these as short hand for the other developers on my team who are less well versed in writing DataMapper queries. Plus, it has a nice side benefit of helping to promote consistency in query results across the application.
I'm sure that I'm missing something completely obvious. Are you able to see what I'm doing wrong?
- ryan
EDIT:
Naturally, no more than 20 seconds after posting this I realized what was going on. After the query is run and the results retrieved, the actual "query" itself is wiped clean just like it would be for any DM object. So I guess, a different question: once get() is called on resolved_media, is there a way for me to restore this "default" query?