如何在OOP中表示平均值和其他总量?

时间:2014-09-03 13:59:29

标签: php laravel query-builder

我有一个名为Product的模型。 Product除其他外还包括价格,类别和创建日期。

我想在许多地方显示一个表格,显示按类别划分的平均价格和平均年龄。有时我只想要一个类别,有时候只需要一切,有时只有库存超过一定时间的产品等。

目前我正在使用Laravel的查询生成器在我的控制器中生成这些数字,然后将其传递给视图。

为了帮助尝试重用它,我需要之前在方法中使用它:

$product_averages_base_query = DB::table('products')
    ->leftJoin('categories', 'products.MakeDescription', '=', 'categories.id')
    ->select(
        DB::raw('count(products.id) as TotalNumber'),
        DB::raw('AVG(Datediff("'.date('Y-m-d').'",products.created)) as AvgDaysInStock'),
        DB::raw('AVG(Price) as AvgPrice')
    );

然后,对于我使用的特定用例:

$averages = $product_averages_base_query->where('categories.name', '=', 'Example 1')->get();

或其他变体。

这感觉真的很糟糕"因为我当然最终会在整个地方复制这段代码。

如何以一种让我更容易重复使用它的方式表示这些数据?我应该上课吗?它应该被称为什么,以及它里面有什么?

我应该以某种方式拥有模型吗?

欢迎任何建议!

2 个答案:

答案 0 :(得分:0)

至于适当的地方,您可以非常轻松地使用查询范围并删除模型中的所有内容。您可能想要从基本查询开始......

public function scopeBaseQuery($query)
{
    return $query->leftJoin('categories', 'products.MakeDescription', '=', 'categories.id')
        ->select(
            DB::raw('count(products.id) as TotalNumber'),
            DB::raw('AVG(Datediff("'.date('Y-m-d').'",products.created)) as AvgDaysInStock'),
            DB::raw('AVG(Price) as AvgPrice')
        );
}

然后继续使用类别名称范围......

public function scopeOfName($query, $name)
{
    return $query->where('categories.name', $name);
}

根据需要添加其他范围。

然后使用它,这将非常容易......

$averages = Product::baseQuery()->ofName('Example 1')->get();

答案 1 :(得分:0)

一种解决方案是为模型创建一个Eloquent类,然后将功能放入一个范围。

class Product extends Eloquent {

    public function scopeAveragesByCategoryName($q, $catName) {
        return $q->leftJoin('categories', 'products.MakeDescription', '=', 'categories.id')
                 ->select(DB::raw('count(products.id) as TotalNumber'),
                          DB::raw('AVG(Datediff("'.date('Y-m-d').'",products.created)) as AvgDaysInStock'),
                          DB::raw('AVG(Price) as AvgPrice'))
                 ->where('categories.name', '=', $catName);
    }

}

$products = Product::averagesByCategoryName('Example 1')->get();
var_dump($products);

或者你可以轻松地将整个事物放入一个函数中。