Correct way to extend base Model to add additional functionality
Good day,
Please assist me with this one. I hit a blank moment suddenly.
I want to extend the base Model functionality by adding my own methods.
This is what I would like to achieve but not working. Should I use abstract class with static methods or?
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
abstract class Base extends Model
{
public function findOrCreate($id) {
$model = self::find($id); //Find Model base on ID
if ($model) {
return $model;
}else{
//Else Return a New Instance...
}
}
}
This is only an example of what I would like to do so please help with example code...
Thanks usman - I know that it exist but I am just using that as an example.
And secondly - on MS SQL firstOrCreate() does not work properly. Complaints about the identity (PK).
So I do want to implement a similar method just as an exercise / learning process.
@Sven0188 I see, If you just want to add a single method then you can also use query macros instead. No need to extend the model, since you will essentially be adding the behaviour to the query builder to achieve this. So, use a macro.
But lets say I have several extended functionality to add.
Would it not be good it create a Base model and then add all my common methods there and the extend all my Models from the Base model?
class Base extends Model {
}
and rest of my Models:
class User extends Base {
}
etc...
But I am not sure about using abstract classes and static methods or how?
I would really love to learn to do this in PHP/Laravel although I appreciate the advise regarding Macros and I will surely look into that as well :)
@Sven0188 Yes, you can always use inheritance for the extanding functionality. That is the main reason for its existance in OOPs :). Just remember if you are overriding the constructor do not forget to call the parent constructor of the model. Add methods as you like and if you want to override the magic methods as well, be careful to do so, because it can potentially break the functionality since a lot of eloquent magic happens inside them.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Base extends Model
{
public static function findOrCreate($id) {
if ( ! is_null($instance = self::find($id)) ) {
return $instance;
}
return self::newInstance();
}
}
and this is the error:
Non-static method Illuminate\Database\Eloquent\Model::newInstance() should not be called statically
I am confused to using static method or not... My understanding limited in PHP/Laravel.
Ok along this line of questioning... I want to use soft deletes in all of my models. Right now I've extended the Model class with BCSModel which has the appropriate use statements. But I would like to have artisan make:model use this extended class. Is this the correct approach, and if not what is a better way to do this?
@mpchean I've done something similar, but ended up making my own artisan command to generate models (with a ton of more optional parameters - including specifying the model it's extending if other than default)
Hi Cronix:
So there is nothing that is going to bite me in the backside if I take the approach of extending Model? I'm sort of surprised Laravel doesn't include this capability, but I will look into creating my own artisan command.
Isn't it a bad practice overwriting the base model? I've always been concerned about deviating from Laravel's patterns, so new team members wouldn't overlook such things.