TL: DR Как использовать whereHas () с настраиваемыми первичными ключами в Laravel 5.4 ^?
Я обновляю свое приложение Laravel CMS до версии 5.4, многие из задействованных моделей стиля мультимедиа имеют версии дляроли пользователей, гео-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 (), SQL, следующий за and exists
, изменился, и я не могу найти, как передать дополнительные параметры в обратный вызов.
Вот пример функции 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
, но запрос, сгенерированныйгдеHas () изменился на это:
Разбит в 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`
Есть ли способ передачи параметров в whereHas () аналогично методу мнения ()?
Я также заново создал запрос, используя конструктор запросов Laravel, и могу предоставить больше информации, если это необходимо, хотяЯ хотел бы решить проблему без нее, если это возможно.