Reputation: 3657
I think I might have found a quirk of the code that allows Laravel Eloquent model methods to be called statically, but could do with some help.
I have a Model called FormSubmission
which extends Eloquent\Model
.
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
class FormSubmission extends Model
{
/**
* Should always return a Collection of FormSubmissions
*
* @param $formSubmissionIds
*
* @return Collection
*/
protected function getFormSubmissions(array $formSubmissionIds) : Collection
{
return FormSubmission::whereIn('id', $formSubmissionIds)->get();
}
}
I needed a place to put some logic that is unique to only 1 type of FormSubmission. As it is not relevant to all forms I did not want to pollute the FormSubmission
model so I have made EmployeeFormSubmission
which extends FormSubmission
.
namespace App;
class EmployeeFormSubmission extends FormSubmission
{
/**
*
*/
public function getTest()
{
$employeeFormSubmission = new EmployeeFormSubmission();
// The resulting Collection will contain instances
// of EmployeeFormSubmission (not FormSubmission).
return $employeeFormSubmission->getFormSubmissions([86]);
}
}
Eloquent Model -> extended by FormSubmission -> extended by EmployeeFormSubmission
The problem...
The strange behaviour which I am having trouble understanding is that if I call the whereIn()
method on FormSubmission
from within EmployeeFormSubmission
like in the getTest() example above, the resulting Collection will contain instances of EmployeeFormSubmission
, even though I am explicitly calling the whereIn()
method on FormSubmission
model.
The behaviour is the same if I use parent::whereIn()
However, if I change FormSubmission::getFormSubmissions()
method to be a public static, it works as expected and returns a Collection of instances of FormSubmission
.
It's as if Laravel/PHP is substituting "FormSubmission::" for "self::" when inside a non-static method on FormSubmission
.
When non-static, it's holding on to the context in which the code is executed and initialising the items within as instances of that class. But when static, it honours the model name referenced in the line of code.
Please help I am a bit stumped.
Upvotes: 1
Views: 421
Reputation: 25906
The reason is that calls to undefined static methods like FormSubmission::whereIn()
don't get handled by __callStatic()
, but by __call()
(PHP is handling incorrectly my static call).
This works:
return FormSubmission::query()->whereIn('id', $formSubmissionIds)->get();
Upvotes: 1