Extending one model with another model in Laravel - php

I am pretty new to laravel and currently exploring its concepts. In some videos I saw a concept of models inheritance. I wonder if we can use models relationships in laravel 5.6 then why we need to inherit models. In which case we need to or should inherit models.
eg Base Model:
class User extends Authenticatable
{
}
eg Child Model:
Class UserTypeOne extends User()
{
}
eg Child Model2:
Class UserTypeTwo extends User
{
}
Thanks in advance.

You don't really need to inherit Models like class inherit. You should use Eloquent Relationship instead. Prior to development, you have to do proper database designing.
https://laravel.com/docs/5.6/eloquent-relationships

Related

How to overwrite an vendor class

How can i overwrite a vendor class?
I'm using Laravel Spark and i wanna have Uuid for all models. Due Spark manage some models inside the package and i don't see a possibility to use my own model for Notifications etc. i would like to overwrite the base Model class from Illuminate\Database\Eloquent\Model, so i could include there my uuid trait.
I tried over the ServiceProvider with:
public function boot()
{
//
$this->app->bind('Illuminate\Database\Eloquent\Model', 'App\Models\Model');
}
But it didn't worked.
Is it possible or maybe exist a better way?
Thanks for any help.
Create a custom model class which will extend the eloquent model.
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class CustomModel extends Model {
// Your implementation
}
And then rest of the models you extend your custom model.
class Test extends CustomModel {
}

How to observe all models implementing an interface in Laravel 5.1?

I have an audit class which extends the Eloquent Model...
class Audit extends Model {
}
I have an auditable interface...
interface IAuditiable {
public function audit();
}
I have a trait which fulfils the interface and defines the relation between the model and the audit...
trait Auditable {
public function audit(){
return $this->hasMany('Audit');
}
}
I have a model which extends the Eloquent Model implements the interface and uses the trait...
class Post extends Model implements IAuditable {
use Auditable;
}
I'd like to add the functionality in there to create or update an audit whenever the Post model is created or updated. I've solved this by registering an observer on the Post which would catch the 'saved' event and add a new audit.
However, there will eventually be many models using implementing IAuditable and using the Auditable trait.
So, my question is, is it possible to implement an observer which would pick up all 'saved' events for any model which implements the IAuditable interface in Laravel 5.1?
You can try hooking into eloquent events. Do something like this in a service provider:
Event::listen(['eloquent.created: *', 'eloquent.updated: *'], function($model) {
// Check if the model implements your interface (could use class_implements(...)
});
I had to do something very similar to what you're looking to do. This solution isn't perfect because you catch events from every model, but it works well enough.
EDIT: Just noticed this question was asked almost two years ago. Hopefully this helps someone out, though :)

Laravel 5.1 - Dry on same characteristics models

In my Laravel 5.1 App I have a lot of aux Models with the same structure. I was thinking in the posibility of make one model and controller for using all of them, but I cannot figure how to do.
I explain, all the database aux tables have the fields ID and name, and are made for CRUD operations and for filling the forms all over the App.
Is possible to specify the table on the methods implemented by Laravel? I mean, stablish the table on construct, on get(), etc. This would made the work a much more simple if I could do AuxTable::create("sex") or even in requests like $request->auxtable("studies")->get().
Am I explaining?
you can do it with single model like below in Model class there is a method called setTable($table) which can set the table name you want to use so consider below
use Illuminate\Database\Eloquent\Model;
class AuxTable implements Model {
//other class properties
}
in your controller use the model like below
class SampleController extends BaseController {
public function index() {
$model = new AuxTable;
$model->setTable('sex');
$model->get();
}
}
this should do the trick

Symfony + Doctrine: Models and Inheritance

I've separated my models from my entities. I have three models with corresponding entities: Review, RatedReview, and ScoredReview. Their relationship is ScoredReview extends RatedReview extends Review.
So for my models I have:
// Project/ReviewBundle/Model/Review.php
class Review
{
}
// Project/ReviewBundle/Model/RatedReview.php
class RatedReview extends Review
{
}
// Project/ReviewBundle/Model/ScoredReview.php
class ScoredReview extends RatedReview
{
}
Then I implement the entities by extending the models, like so:
// Project/ReviewBundle/Entity/Review.php
use Project\ReviewBundle\Model\Review as BaseReview;
class Review extends BaseReview
{
}
// Project/ReviewBundle/Entity/RatedReview.php
use Project\ReviewBundle\Model\RatedReview as BaseRatedReview;
class RatedReview extends BaseRatedReview
{
}
// Project/ReviewBundle/Entity/ScoredReview.php
use Project\ReviewBundle\Model\ScoredReview as BaseScoredReview;
class ScoredReview extends BaseScoredReview
{
}
So the inheritance is happening on the model side. Doctrine can't seem to see this, and maps them to separate tables. I understand this is because Doctrine only looks for entities extending other entities, not entities extending models.
Is there a better way for me to separate the models from the entities, while retaining the ability to extend entities? Is this where traits come in handy?
Put another way, is there anyway that I can have a tree made of models, and a tree made of entities that extends those models?
I've come up with a solution for this issue, and it does involve traits.
What I'm doing is basically trying to create several variations of a table. The relationship between the reviews is more horizontal than vertical (One type of review might have ratings, another one a video, another both). Traits are apparently perfect for horizontal relationships, so instead of creating models for each variation, I create traits.
So now my "models" look like this:
// Project/ReviewBundle/Entity/Review.php
use Project\ReviewBundle\Model\Review as BaseReview;
class Review extends BaseReview
{
}
// Project/ReviewBundle/Entity/RatedReviewTrait.php
trait RatedReviewTrait
{
}
// Project/ReviewBundle/Entity/ScoredReviewTrait.php
trait ScoredReviewTrait
{
}
And my entities look like this:
// Project/ReviewBundle/Entity/Review.php
use Project\ReviewBundle\Model\Review as BaseReview;
class Review extends BaseReview
{
}
// Project/ReviewBundle/Entity/RatedReview.php
use Project\ReviewBundle\Model\RatedReviewTrait;
class RatedReview extends Review
{
use RatedReviewTrait;
}
// Project/ReviewBundle/Entity/ScoredReview.php
use Project\ReviewBundle\Model\RatedReviewTrait;
use Project\ReviewBundle\Model\ScoredReviewTrait;
class ScoredReview extends Review
{
use RatedReviewTrait;
use ScoredReviewTrait;
}
My models stay separated from my entities and as a bonus I decouple the variations from each other – pretty awesome. The only issue I see is that this requires PHP >= 5.4.

Laravel - extending models to controller

Is extending model to a controller a good idea?
Like say I want to make my functions in the model protected instead of public and then extend my model to the controller so that the controller can still call those functions?
Is it a good thing to do? Or should I just leave them public?
No, don't do that! That defeats the whole object of MVC. Leave all functions in the model public unless they are only to be used by that model or related models. In which case they can be private/protected respectively.
If you extend your model to the controller then the controller turns into a model.
I can't imagine how controllers could "extend" your model.
You can extend Eloquent models for example, and make inherited models like:
class ModelB extends ModelA
{
// code
}
class ModelA extends Eloquent
{
protected $something;
//code
}
and then use them in the controller accordingly. Your controllers extend a different class, BaseController and have a different purpose than models to begin with.
So the short asnwer is no.

Categories