Laravel 4:如何为DB :: table添加范围?

时间:2015-02-09 22:26:37

标签: php laravel laravel-4

使用Eloquent模型添加范围很简单:

public function scopeMyScope($query)
{
   // Do stuff to that $query
}

但是如何将范围添加到DB::table

我使用此查询来获取页面视图:

$views = DB::table('page_views')
    ->where('id', $this->id)
    ->where('agent', 'NOT LIKE', '%bot%')
    ->count(DB::raw('distinct session, DATE(created_at)'));

我还会使用其他查询显示最受欢迎的网页等,但条件相同where。因此,我只想定义一次where条件,并在所有其他页面查看DB::table查询中重复使用它们。

4 个答案:

答案 0 :(得分:12)

DB::table不支持范围。你可以做的只是编写一个小函数,用查询做一些事情并返回它。语法不是很好但是有效:

function applyScope($query){
    $query->whereNotNull('deleted_at');
    $query->where('foo', 'bar');
    return $query;
}

然后:

$query = DB::table('page_views')
    ->where('id', $this->id)
    ->where('agent', 'NOT LIKE', '%bot%');
$query = applyScope($query);
$views = $query->count(DB::raw('distinct session, DATE(created_at)'));

或者语法更短:

$views = applyScope( DB::table('page_views')
                       ->where('id', $this->id)
                       ->where('agent', 'NOT LIKE', '%bot%')
         )->count(DB::raw('distinct session, DATE(created_at)'));

答案 1 :(得分:8)

感谢lukasgeiter answer我想到了为此创建一个类,它扩展了DB并返回可以构建的查询的开头:

class PageViewQueryBuilder extends DB {

    public static function table()
    {
        $query = parent::table('page_views')
            ->where('agent', 'NOT LIKE', '%bot%')
            ->where('agent', 'NOT LIKE', '%spider%')
            ->where('agent', 'NOT LIKE', '%crawler%')
            ;

        return $query;
    }
}

我现在可以使用它来创建许多不同的查询,所有查询都具有相同的条件。

获取特定网页的观看次数:

$count = PageViewQueryBuilder::table()
    ->where('page_id', $id)
    ->count(DB::raw('distinct session, DATE(created_at)'));

获取特定网页的所有观看次数:

$views = PageViewQueryBuilder::table()
    ->where('page_id', $id)
    ->orderBy('created_at', 'DESC')
    ->groupBy('session', DB::raw('DATE(created_at)'))
    ->get();

获取过去三个月中最受欢迎的10个页面:

$views = PageViewQueryBuilder::table()
    ->selectRaw('page_id as page_id, count(distinct session, DATE(created_at)) as page_views')
    ->whereRaw('created_at BETWEEN NOW() - INTERVAL 3 MONTH AND NOW()')
    ->groupBy('page_id')
    ->orderBy('page_views', 'desc')
    ->limit(10)
    ->get();

答案 2 :(得分:0)

使用lukas解决方案就像对待美食一样;我从定义了模型的模型中调用范围,只是避免了重复功能。

$query = DB::table('page_views')
    ->where('id', $this->id)
    ->where('agent', 'NOT LIKE', '%bot%');
$query = (new myModel())->scopeMyScope($query);
$views = $query->count(DB::raw('distinct session, DATE(created_at)'));

答案 3 :(得分:0)

您可以创建一个自定义类,该类将所有函数传递给您的自定义查询以外的DB门面。像这样:

<?php

namespace App\Utilities;

use DB;

class CustomDB
{
    private $db;

    private static $instance = null;

    private $exitCalls;

    private function __construct()
    {
        $this->exitCalls = ['get', 'find', 'pluck', 'first', 'value', 'chunk', 'chunkById', 'count', 'max', 'avg', 'exists', 'doesntExist'];
    }

    public function __call($name, $arguments)
    {
        $result = call_user_func_array([self::$instance->db, $name], $arguments);

        if (in_array($name, $this->exitCalls)) {
            return $result;
        }

        return self::$instance;
    }

    public static function table($string)
    {
        if (self::$instance == null) {
            self::$instance = new CustomDB();
        }

        self::$instance->db = DB::table($string);

        return self::$instance;
    }

    public function myCustomQuery()
    {
         self::$instance->db->where('name','=','frank');
         return self::$instance;
    }
}

现在您可以简单地致电:

CustomDB::table('users')->myCustomQuery()->get();