【问题标题】:Laravel Eloquent ORM "whereHas" through tableLaravel Eloquent ORM "whereHas" 通过表
【发布时间】:2014-09-30 11:54:58
【问题描述】:

嘿,我在我的网站 Phones number lookup 上遇到了 Laravel 的问题。我尝试通过联系表选择具有我选择的城市的地方。

我的模型类: 地方类:

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();

错误信息:

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

我知道它缺少“来自”citites 但我不知道如何实现它。

【问题讨论】:

  • 一个地方只有一个联系人,一个联系人只有一个城市,因此一个地方只有一个城市,对吗?

标签: sql laravel orm eloquent


【解决方案1】:

您有 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 在这里根本不起作用

【讨论】:

  • 我一开始就尝试像选项 2 那样做,但我得到这个错误:调用未定义的方法 Illuminate \ Database \ Query \ Builder :: contacts.cities () 尽管我有类联系人功能:公共功能城市()。为什么?
  • @PiotrSuchanek 就像我写的那样,这可以通过我链接的 PR 来实现。目前Eloquent 不支持它。你可以暂时用 1st 代替,或者拉我的那个 PR。
  • 嗨,我尝试了这两种方法,我得到了类似的错误:Unknown column 'cities.contacts_id' in 'on Clause' (SQL: select * from places where (select count(*) from cities Inner Join contacts On contacts 987654338 id 987654339 contacts_id 987654341 id 987654343 places_idcities 987654346 id 987654346 @ 987654346 ) >= 1)。表城市没有列contacts_id。 Places 表有它。有什么解决办法吗?
  • 外键名是什么?您有复数型号名称,这不是 Eloquent 所期望的。这就是为什么它试图猜测密钥(因为你没有在关系上指定它)并寻找contacts_id,而我认为它是contact_id
  • 我添加了这个:return $this->hasManyThrough('Cities', 'Contacts', 'cities_id','contacts_id');并且仍然并且仍然得到相同的错误。我还在我的问题中添加了图片,这可以提供帮助。
【解决方案2】:

由于您知道城市 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');
}

现在您可以查询城市并找到地点。

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

编辑: 在函数中添加了缺少的返回

【讨论】:

  • 我尝试了这个并得到了这个错误:关系方法必须返回一个类型为 Illuminate\Database\Eloquent\Relations\Relation 的对象
  • 这也适用于您的情况,但是@RMcLeod 示例中缺少return。只需在这两种方法中添加return 语句即可
【解决方案3】:
SELECT * from pemeriksaan_ginekologi_iva where id in
(
SELECT m1.id
FROM pemeriksaan_ginekologi_iva m1 LEFT JOIN pemeriksaan_ginekologi_iva m2
 ON (m1.id_klien = m2.id_klien AND m1.id < m2.id)
WHERE m2.id IS NULL
) and id_klien in (select id from klien where id_kelurahan =1)
AND (hasil_periksa='IVA Negatif / Normal')  traslate to laravel

【讨论】:

  • 如果你能解释这是如何解决问题的,这个答案将会大大改善:)
猜你喜欢
  • 2017-05-20
  • 2021-08-23
  • 1970-01-01
  • 2019-12-28
  • 2017-06-09
  • 2020-09-16
  • 2017-05-15
  • 2020-12-23
  • 2016-03-16
相关资源
最近更新 更多