Laravel 4:如果通过查询关系存在关系,则选择行

时间:2013-10-04 08:57:09

标签: orm laravel eloquent

我正在尝试查询产品表,并希望它在存在关系时返回集合。

迭代1 下面查询products表中的所有行,如果$name匹配则延迟加载金属表。这是错误的。

我的路线:

Route::group(array('prefix' => '{api}/v1'), function()
{
    Route::controller('products', 'Api\V1\ProductController');
});

我的控制器:

public function getFilter($metal = null) {
    $products = $this->product;
    if ($metal) {
        $products->with('metal', function($query, $metal) {
            $query->where('name', $metal);
        });
    }
    return Response::api($products->get());
} 

我希望 $products显示metal.name = $metal。例如类似的东西:

$this->products->where('metal.name', $metal)->get;

使用Glad To Help答案的部分解决方案:

这提供了另一种方法2,无需连接。

http://paste.laravel.com/WC4

1 个答案:

答案 0 :(得分:1)

不幸的是,在Eloquent中只用一次滑动就无法做到这一点。

但是,有一种方法可以使用反向关系,如下所示:

public function getFilter($metal = null)
{
    // filter the metals first
    $metals = Metal::with('products')->where('name', '=' , $metal)->get();
    $products = array();
    foreach($metals as $metal)
    {
           // collect the products from the filtered metals
           $products = array_merge($products, $metal->products->toArray() );
    }
    return $products;
}

如果这对您来说不是一个优雅的解决方案,您将需要使用Fluent构建查询并手动加入products x metals表,或者通过覆盖newQuery()方法预先加入它们。

1)替代方法之一。

public function getFilter($metal = null) {
    return DB::table('products')->join('metal', 'products.id', '=' , 'metal.product_id')
                         ->where('metal.name', $name)
                         ->select(array('products.*'));
}

2)替代方法二

class Product extends Eloquent{

public function newQuery($excludeDeleted = true){
        return parent::newQuery()->join('metal','id','=','metal.product_id');
    }

}