Yii2: Polymorphic relations in ActiveRecord ?

Created on 8 Jul 2014  路  13Comments  路  Source: yiisoft/yii2

Hello every body,

At my work we use Laravel's ORM (Eloquent) because it is stand-alone.
This ORM Follow ActiveRecord Pattern (like Yii's ActiveRecord). Laravel implements polymorphic relations and it's very usefull, why yii don't implements it ?

Implements the many to many polymorphics relation would be a good thing !

See laravel doc, for more details : http://laravel.com/docs/eloquent#polymorphic-relations

feature

Most helpful comment

I'm sorry @FabrizioCaldarelli but I'm not agree with you.

Your proposal derives in a non-extensible system.
Each time you need to add a new morphism you will need to make an ALTER TABLE.
Did you think about what will happen when you try to ALTER a table with X millions of registers?

IMHO, I prefer manage the data integrity with other techniques than compromise the extensibility of the system.

All 13 comments

Any reason why this was removed in 2.0?

Not enough time.

+1. Would be awesome if Yii2's ActiveRecord can support Polymorphic Relations, so that I don't need to implement something like state design pattern on my own --- saving a lot of time by avoiding creating a bunch of class files.

+1
It will be so useful ! Actually on Laravel works so good!

https://laravel.com/docs/5.2/eloquent-relationships#polymorphic-relations

which would be the proposed syntax for yii2?

class Like extends ActiveRecord
{
   public static function morphMap()
   {
        return [
            'post' => PostLike::className(),
            'comment' => CommentLike::className(),
        ];
   }

   public static function getMorphClass($type)
   {
         static $map = null;
         if ($map === null) {
             $map = self::morphMap();
         }

         if (class_exist($type) && is_subclass($type, self::className())) {
             return $type;
         }

         return empty($map[$type]) ? null : $map[$type];
   }

   public static function instantiate($row)
   {
         if (!empty($row['type']) && null !== $class = self::getMorphClass($row['type'])) {
             return new $class;
         }

         return new static;
   }
}

instantiate is an already existing method so the implementation would be easy without needing to define extra methods for the morph.

@Faryshta yes. Probably it's better idea to create a recipe in https://github.com/samdark/yii2-cookbook and link to it from AR guide.

@samdark the only question I have is how would the eager loading work since they will point to different tables?

class LikePost extends Like
{
    public function getLiked()
    {
        return $this->hasOne(Post::className(), ['id' => 'liked_id']);
    }
}

and

class LikeComment extends Like
{
    public function getLiked()
    {
        return $this->hasOne(Comment::className(), ['id' => 'liked_id']);
    }
}

how would ->with('likes.liked') work?

I have no idea. Try it.

this really is a nice enhancement. We'll keep it in mind for the future. Feel free to add your usecases as a comment.

Is there any official solution for polymorphic relations?

I think that it is not a good idea, because this breaks right database design. You could not have data integrity. I prefer to have many id fields in the table to match all joined tabled (and guarantee data integrity).

Polymorphic relations can be solved using as many id as many relations the table has.

So my 'likes' table would have: refer_type (post, comment,...), post_id, comment_id, ..., so i can have constraint for every foreign keys.

I'm sorry @FabrizioCaldarelli but I'm not agree with you.

Your proposal derives in a non-extensible system.
Each time you need to add a new morphism you will need to make an ALTER TABLE.
Did you think about what will happen when you try to ALTER a table with X millions of registers?

IMHO, I prefer manage the data integrity with other techniques than compromise the extensibility of the system.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

deecode picture deecode  路  50Comments

spiritdead picture spiritdead  路  67Comments

vercotux picture vercotux  路  47Comments

Faryshta picture Faryshta  路  48Comments

schmunk42 picture schmunk42  路  125Comments