I have two models: NoteItem and TaskItem. Both extends from AbstractStreamItem:
abstract class AbstractCommentsItem
{
…
}
class CommentItem extends AbstractCommentsItem
{
…
}
class TaskItem extends AbstractCommentsItem
{
…
}
Now I want to get repository of both models in one getRepository command.
Is it possible somehow? I thought about single table inheritance, but not sure if it's the right approach.
Yes, Single Table Inheritance is a valid solution here. You will be able to do:
$entityManager->getRepository(AbstractCommentsItem::class);
to get a single repository for all subtypes.
I'm actually doing that in my current project.
Related
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
I'm using Doctrine Filters in my Symfony 3.x application.
Now, I need to filter a joined table, but the addFilterConstraint method allways receive the inheritance root:
In the case of joined or single table inheritance, you always get passed the ClassMetadata of the inheritance root. This is necessary to avoid edge cases that would break the SQL when applying the filters.
This is (part of) my class:
<?php
namespace AppBundle\Filter;
use Doctrine\ORM\Mapping\ClassMetaData;
use Doctrine\ORM\Query\Filter\SQLFilter;
class DataAbstractionFilter extends SQLFilter
{
public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias)
For example, if I had the classes:
class SomeClass {/**/}
class SomeChildClass1 extends SomeClass {/**/}
class SomeChildClass2 extends SomeClass {/**/}
addFilterConstraints will allways receive SomeClass.
Any suggestions? Thanks in advance.
I am attempting to add custom repsitories (contract and Eloquent) in Laravel.
I don't understand where to add them and how to bind with services.
Can any body show the best example for add own wn repository class and interfaces in Laravel?
Thanks in advance
Create a directory in your App folder.Like - App/Acme
Create a Repository File in Acme folder. App/Acme/CustomRepository.php and also import the name space on that Repository file.Like- namespace Acme;
Use your model. Like- use App\Models\User;
In you controller inject the CustomRepository Class.Like-
class CustomController extends Controller{
private $customRepo;
public function __construct(CustomRepository $customRepo)
{
$this->customRepo= $customRepo;
}
}
The way I like to structure my Laravel Code would be:
Models - App\Models\*
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model as BaseModel;
class Model extends BaseModel
{
//
}
Contracts - App\Repositories\Contracts\*
<?php
namespace App\Repositories\Contracts;
interface Repository
{
// All the common methods for eloquent like - all, paginate, find, where, etc...
}
Repository - App\Repositories\Db\*
<?php
namespace App\Repositories\Db;
class ExampleRepository
{
// All the CRUD related methods here...
}
Services - App\Services\*
<?php
namespace App\Services;
class ExampleService
{
// All the logic & business related methods here...
}
This is what I like to structure my code in a laravel way.
Hope this helps!
For make usage of repository pattern (if it is that what you want to say), you have two options, one of it is to implement under a self-defined namespace (let's say App\Repositories), an interface with the methods you want to use in all your repositories, maybe AbstractRepository or something like that, this one choice is painful because of the lot of code you have to write, the other choice (what I would use), is to install the following package https://github.com/andersao/l5-repository, is really useful and already have inside a lot of methods, just follow the instructions of the readme file and you will not have any issue at all implementing this pattern, hope it helps, bests! ;)
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.
my models in CI are set up so that they load "sub"-models whenever they need certain functions. In order to keep my code as accessible and clean as possible, I want those submodels to extend the model they are called to.
So if I have two models:
<?php
class Mymodel extends Model
{
}
And:
<?php
class Submodel extends Model
{
function test() { do something.. }
}
Then I need to, somehow, be able get the submodel to extend mymodel, so that I can do something like $this->mymodel->test(). It doesn't have to be mymodel that submodel extends, it could be any model. Any ideas?
Thanks for your time.
You have an incorrect understanding of inheritance between classes.
Inheritance only flows one way, Down.
if Myodel extends Submodel your $this->mymodel->test() would work, but it does not make sense as sub (child) objects are suppose to inherit from parent objects, not the other way around.
As an analogy, you wouldn't look at a child and tell the parent, "You look just like your child", because it is the child that is a part representation of the parent.
you need to take the word extends very literally, you are literally 'extending' the functionality of the parent.
===================
One way i believe you could accomplish this is to create ghost functions that simply load the proper model and call that models function (though I do not recommend this as it could get very confusing for debugging.
per your example
<?php
class Mymodel extends Model
{
function test() {
$this->load->model('submodel');
$this->submodel->test();
}
}
Submodel
<?php
class Submodel extends Model
{
function test() { do something.. }
}
BUT again, if you are going for clean code, this is NOT the way to go, try and observe inheritance, and design your data with that in mind.
You can create utility model which may extends codeigniter's model and then all your models can extend that utility model. The methods you are going to add to the utility model will be available to all it's child classes aka your models.
How can you call a method which your class does not have or does not inherit from any other classes? Looking at your code, there is no relationship in your classes between Mymodel and Submodel.