我正在将Laravel CMS应用程序升级到5.4,涉及的许多媒体样式模型都针对不同的用户角色,geo-ip等进行了版本控制。我们处理版本控制的方法是通过覆盖primary key
这些模型为ref_id
。
对于Laravel 5.3,外键默认设置如下:
Str::snake(class_basename($this)).'_id'
在5.4中,设置如下:
Str::snake(class_basename($this)).'_'.$this->primaryKey;
在以下位置查看此问题:https://github.com/laravel/framework/issues/17674
由于此更改,Laravel将ref
添加到查询中的列,如下所示:
在5.4中损坏:
select distinct `media`.*, `media_groups`.`media_group_id`
as `pivot_media_group_id`, `media_groups`.`media_ref_id`
as `pivot_media_ref_id`
使用5.3:
select distinct `media`.*, `media_groups`.`media_group_id`
as `pivot_media_group_id`, `media_groups`.`media_id`
as `pivot_media_id`
我在每个关系方法中都添加了额外的参数,大多数时候可以解决该问题。
损坏:
public function opinions() {
return $this->morphToMany(media::class, 'media_group');
}
工作:
public function opinions() {
return $this->morphToMany(media::class, 'media_group',
'media_groups', 'media_group_id', 'media_id', 'bar_id')
}
当我调用whereHas()时,and exists
之后的SQL已经更改,并且我找不到如何将额外的参数传递给回调。
这是我正在调用whereHas函数的示例:
class MediaCategory extends BaseModel
{
protected $table = 'media_category';
protected $primaryKey = 'ref_id';
public $incrementing = false;
public $timestamps = false;
public function media()
{
return $this->morphToMany(media::class, 'media_group');
}
public function mediaByFoo($ref_id)
{
return $this->media()->whereHas('foos', function ($q) use
($ref_id)
{
$q->whereRefId($ref_id)->visitorFilter(); })->get();
}
}
}
我可以将额外的参数传递给media
,但是whereHas()生成的查询已更改为:
在5.4中损坏:
and exists (
select * from `foos`
inner join `media_groups`
on `foos`.`ref_id` = `media_groups`.`media_group_id`
where `media`.`ref_id` = `media_groups`.`media_id`
使用5.3:
and exists (
select * from `foos`
inner join `media_groups`
on `foos`.`ref_id` = `media_groups`.`media_group_id`
where `media_groups`.`media_id` = `media`.`ref_id`
是否有一种类似于Opinions()方法的方法将参数传递给whereHas()?
我还使用Laravel的查询生成器重新创建了查询,并且可以在需要时提供更多信息,尽管我想尽可能地解决此问题。