简体   繁体   中英

Execute whereIn on relationship through another model with eloquent

I'm trying to do some tricky (at least for me) stuff with Eloquent in Laravel 4. For a refinement on a page I need to get all objects of one or more types that lie within one or more provinces. Now I'm trying to figure out how to use Eloquent to retrieve that information for me (assuming it is possible). I think it has to be something like this:

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

That's not working because it says Unknown column 'cities.provinces.id' in 'where clause' .

The following models are being used to accomplish this:

Province

class Province extends Eloquent 
{
    protected $table = 'provinces';

    public function cities(){
        return $this->hasMany('City');
    }
}

City

class City extends Eloquent 
{
    protected $table = 'cities';

    public function province(){
        return $this->belongsTo('Province');
    }

    public function object(){
        return $this->hasMany('Object');
    }

}

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');
}
}

ObjectType

class OutgoingType extends Eloquent 
{
    protected $table = 'outgoing_types';

    public function outgoing(){
        return $this->hasMany('Object');
    }

}

Thanks in advance for your help, I've been trying to figure it out for hours now but I don't seem to come any closer to a solution that works properly.

If you are wanting to use the Eloquent relationships specified in your models then I think you will need to use the

Object::with 

to eager load the relationships ( http://four.laravel.com/docs/eloquent#eager-loading ) rather than

Object::whereIn

->whereIn() expects valid table column names, hence the error about cities.provinces.id not being a valid column as in your cities table it is probably cities.provinces_id, whereas Object::with allows you to load nested relationships with the likes of

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

Adding constraints with this approach is slightly trickier as you would need to do something like

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

}))->get();

Another approach would be to stick with the whereIn approach and use some more traditional joins from the DB query builder http://four.laravel.com/docs/queries#joins

Sorry the above are just pointers rather than an actual solution.

EDIT

Have just had a play and this seems to do what you want:

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

the above will depend on your foreign keys being object_type_id and province_id

SECOND EDIT

A more traditional approach that only gets the objects with the cities with correct province rather than just excluding the city from the objects in the result set would be:

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

There may be a way of achieving the same result with the eloquent object relationships but it evades me at the moment - the join approach is probably more efficient anyway.

Glen

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM