2017-02-18 11 views
1

Таблица структураEloquent: Как найти в текстовых файлах через полиморфные отношения?

entity 
    id - integer 
    title - string 
    ...  

person 
    id - integer 
    name - string 
    ... 

customers 
    id - integer 
    body - text 
    concrete_id - integer 
    concrete_type - string 

Модель:

class Customer extends Model 
{ 
    ... 
    public function concrete() 
    { 
     return $this->morphTo(); 
    } 
    ... 
} 

Person и Entity модель имеет

public function customers() 
{ 
    return $this->morphMany(Customer::class, 'concrete'); 
} 

Как найти все клиент, где типа является 'лицом' и где y.title = 'abc'?

Я пытаюсь сделать что-то вроде этого,

$obj = Customer::whereHas(['concrete' => function($query){ 
     $query->where('title', 'like', 'foo%'); 
    }])->get(); 

, но у меня есть ошибка:

ContextErrorException in Builder.php line 825: Warning: strpos() expects parameter 1 to be string, array given

Например, я могу сделать это с помощью нативного запроса MySQL:

SELECT * 
FROM `customers` 
LEFT JOIN `entities` ON (entities.id = customers.concrete_id) 
WHERE `concrete_type` = "entity" AND entities.title LIKE "%foo%" 

Как это сделать через Eloquent?

ответ

0

Вы работаете в правильном направлении, попробуйте этот код:

Customer::whereHas('concrete', function ($query) { 
      $query->where('title', 'like', 'foo%') 
     })->get(); 

Или вы можете попробовать другой способ:

Entity::has('concrete')->where('title', 'like', 'foo%')->get() 
+0

гм, нет, это dosn't работа обусловлено в этом случае конкретная модель не типа определены. Модель лица не имеет столбца заголовка. Мне нужен поиск текста только для клиентов типа Entity. – Stanislav

+0

Мне интересно :) ... update answer –

+0

Ваш второй метод - это хорошо работать. Но проблема в том, что это решение возвращает коллекцию моделей Entity. Но мне нужна коллекция клиентов. Я обновил вопрос и добавил пример решения через собственный запрос SQL. Посмотрите, и вы лучше поймете проблему. – Stanislav

0

переписал ответ в соответствии с вашими сырым MySQL:

Customer:: 
     ->join('entities', function($join) 
     { 
      $join->on('entities.id', '=', 'customers.concrete_id') 
       ->where('entities.title', 'like', 'foo%'); 
     }) 
     ->get(); 

Надеюсь, это поможет :)

+0

Спасибо за предложение, но это решение также работает неправильно. Потому что в результате нашли все типы клиентов (все записи из таблицы клиентов и присоединились к каждой из них записи сущностей.Вы можете вызвать toSql() вместо get() и посмотреть, что в запросе отсутствует общее условие «где» для разделения конкретного типа клиента.)) – Stanislav

0

Laravel сейчас не поддерживает 'whereHas' для 'MorphTo' отношений.

Look laravel/framework issue 5429

И, если вы хотите, чтобы делать то, что запланировано, вы can use BelongsToMorph relation.

Я добавил к модели Customer:

public function entity() 
{ 
    return BelongsToMorph::build($this, Entity::class, 'concrete'); 
} 

и после этого, запроса работает, как это нужно:

Customer::whereHas('entity', function ($query) { 
     $query->where('entities.title', 'like', '%foo%'); 
    })->get()->toArray();