通过另一个具有雄辩的模型在关系上执行其中


Execute whereIn on relationship through another model with eloquent

我正在尝试在 Laravel 4 中使用 Eloquent 做一些棘手的事情(至少对我来说)。为了对页面进行优化,我需要获取位于一个或多个省份内的一个或多个类型的所有对象。现在我正在尝试弄清楚如何使用 Eloquent 为我检索该信息(假设有可能)。我认为它必须是这样的:

 Object::whereIn('objectType', $objectTypeArray)->whereIn('cities.provinces.id', $provinceIdArray)->paginate(15);

这是行不通的,因为它说Unknown column 'cities.provinces.id' in 'where clause'.

以下模型用于实现此目的:

class Province extends Eloquent 
{
    protected $table = 'provinces';
    public function cities(){
        return $this->hasMany('City');
    }
}

城市

class City extends Eloquent 
{
    protected $table = 'cities';
    public function province(){
        return $this->belongsTo('Province');
    }
    public function object(){
        return $this->hasMany('Object');
    }
}

对象

class Object extends Eloquent 
{
    protected $table = 'objects';
    public function city(){
        return $this->belongsTo('City');
    }
    public function address(){
        return $this->belongsTo('Address');
    }
public function object_type(){
    this->belongsTo('ObjectType');
}
}

对象类型

class OutgoingType extends Eloquent 
{
    protected $table = 'outgoing_types';
    public function outgoing(){
        return $this->hasMany('Object');
    }
}

提前感谢您的帮助,我已经尝试了几个小时,但我似乎并没有更接近正常工作的解决方案。

如果您想使用模型中指定的雄辩关系,那么我认为您需要使用

Object::with 

急切加载关系 (http://four.laravel.com/docs/eloquent#eager-loading) 而不是

Object::whereIn

->whereIn() 需要有效的表列名,因此关于 cities.provinces.id 不是有效列的错误,因为它可能是cities.provinces_id的,而 Object::with 允许您加载嵌套关系,

例如
Object::with('city.province')->get(). 

使用此方法添加约束稍微棘手一些,因为您需要执行以下操作

Object::with(array('city' => function($query)
{
    $query->whereIn('city_id', $array);
}))->get();

另一种方法是坚持使用 whereIn 方法,并使用数据库查询构建器中的一些更传统的连接 http://four.laravel.com/docs/queries#joins

抱歉,以上只是指针,而不是实际的解决方案。

编辑

刚刚玩了一出戏,这似乎可以做你想做的事:

Object::whereIn('object_type_id', $object_type_array)->with(array('city' => function($query) {
                    $query->whereIn('province_id', $province_id_array);
                }))->get();

以上将取决于您的外键是否object_type_id和province_id

第二次编辑

一种更传统的方法是,仅获取具有正确省份的城市的对象,而不仅仅是从结果集中的对象中排除城市:

$objects = Object::join('cities', 'city_id', '=', 'cities.id')
            ->whereIn('objects.object_type_id', $object_type_array)
            ->whereIn('cities.province_id', $province_id_array)->get()

可能有一种方法可以通过雄辩的对象关系实现相同的结果,但目前它回避了我 - 无论如何,连接方法可能更有效。

幽谷