Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel 4: How to apply a WHERE condition to all queries of an Eloquent class?

I'm trying to implement an "approved' state for a table I have, it's pretty straightforward, basically, if the row's approve column equals 1; that row should be retrieved, otherwise it shouldn't.

The problem is, now I have to go through the whole codebase and add a WHERE statement(i.e., function call) which is not only time consuming but also inefficient(if I ever want to remove that feature, etc.)

How can I do that? Is it as easy as adding $this->where(..) inside the Eloquent child class' constructor? Wouldn't that affect other CRUD operations? such as not updating an unapproved row?

like image 870
Abdulaziz Avatar asked Sep 07 '13 23:09

Abdulaziz


1 Answers

The answer was given when there was no query scope feature available.

You can override the main query, only for the Post model, like

class Post extends Eloquent
{
    protected static $_allowUnapprovedPosts = false;

    public function newQuery()
    {
        $query = parent::newQuery();

        if (!static::$_allowUnapprovedPosts) {
            $query->where('approved', '=', 1);
        } else {
            static::$_allowUnapprovedPosts = false;
        }

        return $query;
    }

    // call this if you need unapproved posts as well
    public static function allowUnapprovedPosts()
    {
        static::$_allowUnapprovedPosts = true;

        return new static;
    }
}

Now, simply use anything, but unapproved users won't appear in the result.

$approvedPosts = Post::where('title',  'like', '%Hello%');

Now, if you need to retrieve all posts even unapproved ones then you can use

$approvedPosts = Post::allowUnapprovedPosts()->where('title',  'like', '%Hello%');

Update (Using the query scope):

Since, Laravel now provides Global Query Scopes, leverage that instead of this hacky solution, notice the date of this answer, it's too old and so much things changed by now.

// Using a local query scope
class Post extends Eloquent
{

    public function scopeApproved($query)
    {
        return $query->where('approved', 1);
    }
}

You can use it like:

$approvedPosts = Post::approved()->get();
like image 86
The Alpha Avatar answered Oct 14 '22 13:10

The Alpha