I've created a BaseModel class, which extends from Model. It seemed like everything was working fine, but now I've run into a problem when saving. I'm overriding the save() method in this BaseModel. I'd just like to add some attributes to the model before saving. So I do that, then call return parent::save($options);
. The method signature is still the same: public function save(array $options = [])
.
It appears to be grabbing the name of the BaseModel class for the table name when performing the insert (it's using base_models as the table name), rather than the actual model that is being saved. Has anyone run into this before? What is the proper way of extending from the model class?
I originally created some traits to handle some extra functionality, but thought it would be a better idea to just create a base model and have my models extend from that instead.
Laravel will use snake case of the class name by default (the class where
save
method is called), if no$table
instance variable is set. In your case it will use snake case of theBaseModel
as a table name. You have two solutions:Solution 1:
In classes which extends
BaseModel
add the$table
instance variable as follow:Solution 2:
You can use Laravel Eloquent's Events, which allows you to hook into various points in the model's lifecycle.
You can hook into the
save
method as follow and make your changes. You can use these methods in yourBaseClass
, in traits, etc. For example in yourBaseModel
:The above will always call
isValid
before a model is saved into the storage. In this case it will return false and will not save the object.For more info see the official docs here. Let me know if it isn't clear.
I realized that I previously had a static method that was creating an instance of itself using new self() and would set a few attributes, back when I was using the methods from a trait. It was fine before, but now since I moved the methods into the base model, that method was actually being called on the base model itself rather than the class that had the trait.
I was basically using the static method to instantiate the class, as I've read it's one way to avoid cluttering the constructor. But I just opted to do it in the constructor this time around since it made sense, so that was my solution.
In your model (the child one that extends the base model) add the table name explictly for example: