3

I got 3 models, Article, Building, Person.

  1. These models need to reference each other in a few ways. For example the building needs to be able to reference collections of Person like $building->architects(), $building->owners(), a article might reference collections of Person with $article->authors() and Person might reference collections of Building like $person->owned_buildings()

  2. Each model should have a function like "references" to get a collection of mixed models.

I'm thinking that this should be possible with something like:

class Article extends Eloquent {
    public function referenceable()
    {
        return $this->morphTo();
    }

    public function authors()
    {
        return $this->morphMany('Person', 'referenceable');
    }
}

class Building extends Eloquent {
    public function referenceable()
    {
        return $this->morphTo();
    }

    public function architects()
    {
        return $this->morphMany('Person', 'referenceable');
    }
}

class Person extends Eloquent {
    public function referenceable()
    {
        return $this->morphTo();
    }

    public function owned_buildings()
    {
        return $this->morphMany('Building', 'referenceable');
    }
}

So the question is what would the pivot table look like?

2 Answers2

7

You can define a belongsTo using a morphMany-style relationship by adding a where to the mix:

  public function followers() {
    return $this
      ->belongsToMany('User', 'follows', 'followable_id', 'user_id')
      ->where('followable_type', '=', 'Thing');
  }

The where will simply be sure Eloquent doesn't mismatch IDs.

Hope that helps!

BigBlueHat
  • 2,355
  • 25
  • 30
  • Laravel 4.1 now supports one-to-one and one-to-many polymorphic relationships. http://laravel.com/docs/eloquent#polymorphic-relations – dwenaus May 12 '14 at 17:20
1

Polymorphic relationships are basically 1-to-many relationships. They allow you to reuse a model on many other models.

For instance if Post has many images, and a User might have many avatars, you can use the same image models without conflict. So instead of setting an image with a user_id field and a post_id field, you can use a generic imageable_id.

You require a many-to-many relationship which is not currently supported with Eloquent's morphMany()

You can do several types of pivot tables for that. For instance set up two architect/building and owner /building pivot tables separately with building_id and person_id fields. Or you could setup a single pivot table with an extra 'type' field to define the role

BenG
  • 1,756
  • 15
  • 17
  • Okay, well if I setup buildings_persons and want to use a type field which can be "architect" and "owner" for example, how would I define that with a belongsToMany? – Andreas Franzén Apr 22 '13 at 07:53