3

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?

2
  • 2
    Have you looked at doctrine inheritance? doctrine-orm.readthedocs.org/en/latest/reference/… Seems like single table inheritance is what you are looking for. Commented Apr 22, 2014 at 13:10
  • @Cerad I am using single table inheritance, and it normally works awesome. The problem here was that single table inheritance requires entities extending each other directly, rather than extending models that extend each other. Yet I wanted my logic for say ScoredReviews in a model, not in an entity. I got around that by using just one model for the base class and traits for the sub classes. Commented Apr 22, 2014 at 22:01

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

@n.1 Thanks, I had to wait 48 hours and forgot to come back.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.