Laravel красноречиво где или где с принадлежитtomany

Сегодня я могу найти то, чего не ожидал

namespace App\Models;



use Illuminate\Database\Eloquent\Model;

class News extends Model
{
protected $table="news";


public function media(){
    return $this->belongsToMany(Media::class, "news_medias");
}

}

Это моя новостная модель

News::find(20)->media()->where("medias.id",36)->orWhere("medias.type",1)->get()

При этом вызове я ожидаю, что буду искать носитель с идентификатором 36 или носитель с типом 1 в средствах массовой информации, связанных с новостями с идентификатором 20.

SELECT `medias`.*, `news_medias`.`news_id` as `pivot_news_id`, `news_medias`.`media_id` as `pivot_media_id` 
FROM `medias` inner join `news_medias` on `medias`.`id` = `news_medias`.`media_id` 
WHERE `news_medias`.`news_id` = 20 and `medias`.`id` = 36 or `medias`.`type` = 1

это то, что мне дает журнал запросов, и это не кажется правильным, так как он должен быть

SELECT `medias`.*, `news_medias`.`news_id` as `pivot_news_id`, `news_medias`.`media_id` as `pivot_media_id` 
FROM `medias` inner join `news_medias` on `medias`.`id` = `news_medias`.`media_id` 
WHERE `news_medias`.`news_id` = 20 and (`medias`.`id` = 36 or `medias`.`type` = 1)

Моя версия - Laravel 5.6

Или я ошибаюсь?

Спасибо!

2
0
1 027
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Это должно работать:

News::find(20)->media()->where(function ($q) {
    $q->where("id",36)->orWhere("type",1);
})->get();

Eloquent не добавляет скобки при использовании оператора orWhere, вам нужно создать подзапрос для желаемого результата

И этого никак нельзя избежать, правда? Не следует ли автоматически делать это с помощью a ownToMany?

Kolos Feri Fazekas 10.08.2018 17:32

Честно говоря, я не знаю способа избежать этого, это внутреннее поведение Eloquent.

gbalduzzi 10.08.2018 17:36

Вам следует изменить свой запрос на следующее:

Media::where('id',1)
     ->orWhere(function($query) {
           $query->where('type',1)
                ->whereHas('news', function($q) {
                    $q->where('id',20);
                 };
      })->get();

Он в основном ищет средства массовой информации с идентификатором один или средства массовой информации с типом 1 и связан с новостями с идентификатором 20.

Попробуйте этот запрос:

News::with(["media" => function($query){
  $query->where("medias.id", "=", 36)->orWhere("medias.type", "=", 1);
}])->find(20)->media;

Это делает запрос news, а также запрашивает отношение media для любых записей medias, где id равно 36 или type равно 1. Затем использование ->find(20) вернет вашу модель News, а доступ к ->media вернет коллекцию, ограниченную вашими параметрами в операторе ->with(). .

Другие вопросы по теме