laravel/laravel — pull request #816 by axelarge (2012-06-14 09:45:12+00:00)
Title: Add support for chainable custom finder methods/scopes

This change adds a simple mechanism to reuse finder methods, in the vein of eloquent's own `where()`.

Currently you can create static methods on your models that perform a similar task, but it's not possible to combine them, because they return a Query object. Consider this example:

```php
class MacGuffin {
public static function with_foos() {
return static::with('foos');
}

public static function where_bar() {
return static::where('bar', '=', MAGIC_NUMBER);
}
}

// somewhere else:
MacGuffin::with_foos(); // returns a Query, that doesn't have access to where_bar()!
```

Now we can use these methods in our controllers to hide more logic in the model. However if we want to fetch some macguffins with both conditions, we have no choice but to write it all out in the controller (dirty code) or create another method that combines both of these helpers (lots code duplication with a combinatorial amount of methods).

If this change is implemented, it would be trivial to create these methods as chainable by making them instance methods and prefixing them with an underscore:

```php
class MacGuffin {
public function _with_foos() {
return static::with('foos');
}

public function _where_bar() {
return static::where('bar', '=', MAGIC_NUMBER);
}

public function _for_index() {
return $this->with_foos()->with_bars()->paginate(); // No code duplication here!
}
}
```

Currently Eloquent use this approach internally for the `where()` method, that's why i used the underscore-prefixed naming.

If there's fear of unexpected "magic" method calls, it might be a better idea to create an array with allowed methods, such as `public static $finder_methods = array('with_foos', 'where_bar');` (then the underscore prefix could be dropped as well), but it seemed that this goes better with Laravel's zero-config approach.