Recently I just realized that Laravel generates a static method with column name when joined in a where clause using camel case
example
$user = User::whereName('john')->first(); // added `name` as a column name
When called this code to SQL it generates
$user = User::whereName('john')->toSql();
//it returns
select * from `users` where `name` = ?
This indeed gives expected result as it returns a user with name john
.
I have searched Laravel documentation but can't find this function or where it was defined.
All I need is clarification if this method is good or best so that I can continue using it and as well know how the method is generated inside Laravel framework or any other means
If you're asking where is the code responsible for it to work, it's using the magic method __call()
(__callStatic()
before that to make an instance) in the class Illuminate\Database\Query\Builder
/**
* Handle dynamic method calls into the method.
*
* @param string $method
* @param array $parameters
* @return mixed
*
* @throws \BadMethodCallException
*/
public function __call($method, $parameters)
{
if (static::hasMacro($method)) {
return $this->macroCall($method, $parameters);
}
if (Str::startsWith($method, 'where')) {
return $this->dynamicWhere($method, $parameters);
}
static::throwBadMethodCallException($method);
}
precisely in the condition Str::startsWith($method, 'where')
which redirect the call to dynamicWhere()
/**
* Handles dynamic "where" clauses to the query.
*
* @param string $method
* @param array $parameters
* @return $this
*/
public function dynamicWhere($method, $parameters)
{
$finder = substr($method, 5);
$segments = preg_split(
'/(And|Or)(?=[A-Z])/', $finder, -1, PREG_SPLIT_DELIM_CAPTURE
);
// The connector variable will determine which connector will be used for the
// query condition. We will change it as we come across new boolean values
// in the dynamic method strings, which could contain a number of these.
$connector = 'and';
$index = 0;
foreach ($segments as $segment) {
// If the segment is not a boolean connector, we can assume it is a column's name
// and we will add it to the query as a new constraint as a where clause, then
// we can keep iterating through the dynamic method string's segments again.
if ($segment !== 'And' && $segment !== 'Or') {
$this->addDynamic($segment, $connector, $parameters, $index);
$index++;
}
// Otherwise, we will store the connector so we know how the next where clause we
// find in the query should be connected to the previous ones, meaning we will
// have the proper boolean connector to connect the next where clause found.
else {
$connector = $segment;
}
}
return $this;
}