I have developed a package to enable search method on Eloquent models with JSON.
The engine currently works in a way that a query is appended for supported parameters depending on values provided.
Builder::macro('search', function (Request $request) {
/**
* @var $this Builder
*/
$searcher = new Searcher($this, $request);
$searcher->search();
return $this;
});
Which in turn runs the following:
/**
* Perform the search
*
* @throws Exceptions\SearchException
*/
public function search(): void
{
$this->appendQueries();
Log::info('[Search] SQL: ' . $this->builder->toSql());
}
/**
* Append all queries from registered parameters
*
* @throws Exceptions\SearchException
*/
protected function appendQueries(): void
{
foreach ($this->requestParametersConfig->registered as $parameter) {
$requestParameter = $this->createRequestParameter($parameter);
$requestParameter->appendQuery();
}
}
protected function createRequestParameter($parameter): AbstractParameter
{
return new $parameter($this->request, $this->builder, $this->modelConfig);
}
Request parameters are registered within configuration file and point to request parameter classes to have everything modular.
Now this works great if used on a something like index endpoint or a custom search endpoint, but I would like to extend the functionality to show as well. The issue being here that with route model binding, the model is already loaded when I fetch it.
Let's take relationships for example. I have a request parameter which when used loads relationships on a given model:
www.example.com/api/contacts?relations=(phones)
will load phones relations on Contact model by doing this:
/**
* Append the query to Eloquent builder
* @throws SearchException
*/
public function appendQuery(): void
{
$arguments = $this->getArguments();
$this->builder->with($arguments);
}
But when I do a ->with on already loaded model followed by ->get(), I just get list of all models with loaded relation.
Is there a way to "tap into" already loaded model with query builder, or is it at this point already done deal, and I should pick up the ID on show route instead of resolving it, and then assemble the query?