Set the Default Query Value on Laravel 4 Eloquent Model

Tags: October 4, 2013 7:01 AM

Sometimes we want to apply some default query to the Eloquent Model. In an example, suppose we have Post model that contains all posts. When retrieving the post we want to exclude post with status 'deleted' and 'draft'.

<?php
/**
 * Base class for all model
 */
namespace Acme\Models\BaseModel;

use Illuminate\Database\Eloquent\Model as Eloquent;

abstract class BaseModel extends Eloquent
{
    /**
     * Default value for this model. I.e. getting records that only
     * meet certain criteria.
     *
     * @var Boolean
     */
    protected static $useDefaultQuery = true;

    /**
     * The method that set flag for using default value or not.
     *
     * @return Illuminate\Database\Eloquent\Model
     */
    public static function noDefault()
    {
        static::$useDefaultQuery = false;
        
        return new static;
    }

    /**
     * All model should implements the default query here.
     */
    abstract protected function myDefaultQuery($query);

    /**
     * Override the laravel default newQuery() method so we can use the default value.
     */
    public function newQuery($excludeDeleted = true)
    {
        // Get the parent result
        $query = parent::newQuery($excludeDeleted);

        // Let's do the query if only the $useDefaultQuery property is true.
        if (static::$useDefaultQuery === true) {
            if (method_exists($this, 'myDefaultQuery') === true) {
                $query = $this->myDefaultQuery($query);
            }
        }

        return $query;
    }
}
Post model should extends from Acme\Models\BaseModel to implement the default query.
<?php
/**
 * Post model for retrieving all blog post.
 */
use Acme\Models\BaseModel;

class Post extends BaseModel
{
    /**
     * Apply the default query to the model.
     */
    protected function myDefaultQuery($query)
    {
        return $query->whereNotIn('post_status', array('deleted', 'draft'));
    }
}
If we want to disable the default query just wall the static method `noDefault()`.
// disable the default query
$posts = Post::noDefault()->get();

Share on Facebook Twitter