首页 文章

Laravel Eloquent ORM“whereHas”通过表

提问于
浏览
7

嘿,我和Laravel有问题 . 我尝试通过联系表选择有我选择的城市的地方 .

我的模型类:Places类:

class Places extends Eloquent {
    public function contacts()
    {
        return $this->hasOne('Contacts');
    }
     public function clubs()
     {
        return $this->hasOne('Clubs');
     }    
}

联系人类:

class Contacts extends Eloquent {
     public function cities()
     {
         return $this->hasOne('Cities');
     }
   }

城市类:

class Cities extends Eloquent {

 }

我的查询:

$view->clubs = Places::whereHas('contacts',function ($q) use($city_id){
           $q->where('contacts', function ($q) use($city_id){
               $q->where('id', $city_id);
            });
        })->get();

错误消息:

MySQL服务器版本,在第1行的'where id =?))> = 1'附近使用正确的语法(SQL:select * from places where(select count(*)from contacts where contacts.places_id = places.id and contacts =(select * where id = 2223))> = 1)

我知道它缺少"from" citites 但我不知道如何实现它 .
Model relationships

2 回答

  • 0

    您有3个使用关系的选项:

    1最直接的解决方案:

    Places::whereHas('contacts',function ($q) use ($city_id){
           $q->whereHas('cities', function ($q) use ($city_id){
               $q->where('id', $city_id);
            });
        })->get();
    

    2与上述相同,但使用此PR:https://github.com/laravel/framework/pull/4954

    Places::whereHas('contacts.cities', function ($q) use ($city_id){
            $q->where('id', $city_id);   
        })->get();
    

    3使用 hasManyThrough 关系:

    // Place model
    public function cities()
    {
      return $this->hasManyThrough('City', 'Contact');
    }
    
    // then
    Places::whereHas('cities',function ($q) use ($city_id){
       $q->where('cities.id', $city_id);
    })->get();
    

    编辑

    拥有您的架构显然没有任何建议或您的原始设置可以工作 .

    这是一个多对多关系,在Eloquent中是 belongsToMany

    // Places model
    public function cities()
    {
      return $this->belongsToMany('Cities', 'contacts', 'places_id', 'cities_id')
        ->withPivot( .. contacts table fields that you need go here.. );
    }
    
    // Cities model
    public function places()
    {
      return $this->belongsToMany('Places', 'contacts', 'cities_id', 'places_id')
        ->withPivot( .. contacts table fields that you need go here.. );
    }
    

    然后你可以调用这样的关系:

    $city = Cities::first();
    $city->places; // collection of Places models
    
    // contacts data for a single city-place pair
    $city->places->first()->pivot->open_hours; // or whatever you include in withPivot above
    

    现在,还有另一种设置方法,如果您还需要 Contacts 模型本身:

    // Places model
    public function contact()
    {
      return $this->hasOne('Contacts', 'places_id');
    }
    
    // Contacts model
    public function city()
    {
      return $this->belongsTo('Cities', 'cities_id');
    }
    
    public function place()
    {
      return $this->belongsTo('Places', 'places_id');
    }
    
    // Cities model
    public function contact()
    {
      return $this->hasOne('Contacts', 'cities_id');
    }
    

    然后:

    $city = Cities::first();
    $city->contact; // Contacts model
    $city->contact->place; // Places model
    

    hasManyThrough 根本不会在这里工作

  • 12

    如您所知,城市ID,您可以从中找到相应的地方,您可以在城市开始并回到这个地方 . 为此,您需要定义关系的倒数 .

    // Add this function to your Cities Model
    public function contact()
    {
        return $this->belongsTo('Contact');
    }
    
    
    // Add this function to your Contacts Model
    public function place()
    {
         return $this->belongsTo('Places');
    }
    

    现在您可以查询City并找到Place .

    $place = Cities::find($city_id)->contact->place;
    

    EDIT: 在函数中添加了缺失的返回

相关问题