Использование Laravel 5.8.11 У меня полиморфное отношение ко многим, у клиентов может быть много адресов, в другом случае в этом случае могут быть адреса, поэтому это полиморфно. (вызываемые адреса)
Я также сохраняю полиморфное отношение "имеет один" к текущему адресу клиента (вызываемый адрес)
Когда я пытаюсь выполнить этот запрос:
return Client::with('address')
->where('first_name', 'like', '%' . $search . '%')
->orWhere('last_name', 'like', '%' . $search . '%')
->get();
Я получаю некоторые странные результаты обратно. Я получаю всех клиентов, но адрес есть только у последнего клиента.
При проверке начальных данных присутствуют все остальные адреса, и если я изменю результаты, отправив в других критериях поиска, последний человек всегда будет возвращаться с правильным адресом, в то время как у других всегда будет нулевой.
Это не проблема пользовательского интерфейса, так как я просто вывожу результат в модульном тесте
Вот код для отношений на клиентском объекте.
/**
* Get the address records associated with the Model.
*/
public function addresses() :MorphMany
{
return $this->morphMany(Location::class, 'has_location')->latest();
}
/**
* Get the latest address record associated with the Model.
*/
public function address() :MorphOne
{
return $this->morphOne(Location::class, 'has_location')->latest('id')->limit(1);
}
Когда я пытаюсь выяснить, что я называю из базы данных, я пытаюсь перехватить отправляемый SQL. Я просто использую простую функцию, чтобы перестроить полный SQL для облегчения чтения с помощью этого:
function ddsql($builder, $replace = false)
{
if (!$replace)
return ddf([$builder->toSql(), $builder->getBindings()]);
$sql = $builder->toSql();
ddf(Str::replaceArray('?', $builder->getBindings(), $sql));
}
ddf () - это в основном dd (), но некоторые помощники показывают, что вызывающая функция из журналов обратной трассировки не имеет никакого отношения.
Я использую его следующим образом в исходном кодовом блоке
ddsql(
Client::with('address')
->where('first_name', 'like', '%' . $search . '%')
->orWhere('last_name', 'like', '%' . $search . '%')
);
, который возвращает первый запрос, но не шаг загрузки, который, вероятно, там, где проблема.
Array
[
"select * from `clients` where `first_name` like ? or `last_name` like ?",
[
"%co%",
"%co%"
]
]
Однако я получаю только первый запрос от разработчика.
Есть ли способ получить все запросы?
Любые советы приветствуются.
UPDATE:
Per @ tim-lewis, (спасибо) Я обновил функцию, которую я использовал, чтобы это было некрасиво, но выполняет свою работу.
/** @test */
public function clients_matching_search_are_returned_with_their_addresses() {
$client1 = ObjectFactory::clientWithAnAddress(['client'=>['first_name'=>'Test 1']]);
$client2 = ObjectFactory::clientWithAnAddress(['client'=>['first_name'=>'Test 2']]);
$client3 = ObjectFactory::clientWithAnAddress(['client'=>['first_name'=>'Test 3']]);
ddSqlCollection(function(){return Client::with('address')->get();});
}
//WHERE ddSqlCollection is the following
function ddSqlCollection($callback, $replace = false){
$callback = $callback ?: function () {
return true;
};
DB::flushQueryLog();
DB::enableQueryLog();
$callback();
DB::disableQueryLog();
ddf(DB::getQueryLog());
}
Я уверен, что есть более красивый способ, и я все еще не уверен, почему данные, которые я получаю, не соответствуют тому, что я считаю, что SQL должен возвращаться, однако я спрошу тех, кто более сфокусирован вопрос.
Вот результат, который ожидался:
"ddSqlCollection(["Closure"])"
"Tests\Feature\Clinet\SearchTest\clients_matching_search_are_returned_with_their_addresses([])"
"-------------------------------------------"
array:2 [
0 => array:3 [
"query" => "select * from "clients""
"bindings" => []
"time" => 0.06
]
1 => array:3 [
"query" => "select * from "locations" where "locations"."has_location_id" in (1, 2, 3) and "locations"."has_location_type" = ? order by "id" desc limit 1"
"bindings" => array:1 [
0 => "App\Client"
]
"time" => 0.19
]
]