Tuesday, April 4, 2017

Laravel many to many with 3 models

I've been struggling with a issue the last couple of days. I've just started using Laravel and are getting real fond of the Eloquent-syntax! But there's a issue when I'm trying to get the correct relation between three models.

I've got this setup:

programs table contains

  • event_id
  • user_id
  • role_id

In my Event-model I've got

public function programs(){
    return $this->hasMany(Program::class);
}

In my User-model I've got

public function programs(){
    return $this->hasMany(Program::class);
}

In my Role-model I've got

public function programs(){
    return $this->hasMany(Program::class);
}

And my Program-model contains

public function event(){
    return $this->belongsTo(Event::class);
}
public function user(){
    return $this->belongsTo(User::class);
}
public function role(){
    return $this->belongsTo(Role::class);
}

And I need to get the following result

Events -> Users -> Role

In my controller I've got $events = Event::with('programs.role.programs.user')->get();

Which is producing this:

{
"id": 2,
"name": "Concert: Freddy Kalas",
"description": "Freddy Kalas konsert",
"user_id": 2,
"time_from": "12.04.2017 22:00:00",
"time_to": "12.04.2017 23:00:00",
"created_at": "2017-03-20 18:28:44",
"updated_at": "2017-03-20 18:28:44",
"programs": [
  {
      "id": 2,
    "event_id": 2,
    "user_id": 2,
    "role_id": 1,
    "created_at": null,
    "updated_at": null,
    "role": {
      "id": 1,
      "name": "Camera operator",
      "description": "Operates ordinary cameras or PTZ cameras",
      "created_at": "2017-03-20 20:11:06",
      "updated_at": "2017-03-20 20:11:06",
      "programs": [
        {
            "id": 1,
          "event_id": 3,
          "user_id": 2,
          "role_id": 1,
          "created_at": null,
          "updated_at": null,
          "user": {
            "id": 2,
            "name": "Dummy Dum",
            "email": "dummy@example.com",
            "created_at": "2017-03-20 16:45:09",
            "updated_at": "2017-03-20 16:45:09"
          }
        },
        {
            "id": 2,
          "event_id": 2,
          "user_id": 2,
          "role_id": 1,
          "created_at": null,
          "updated_at": null,
          "user": {
            "id": 2,
            "name": "Dummy Dum",
            "email": "dummy@example.com",
            "created_at": "2017-03-20 16:45:09",
            "updated_at": "2017-03-20 16:45:09"
          }
        }
      ]
    }
  }
]
},
{
    "id": 3,
"name": "Prøveproduksjon",
"description": "Prøveproduksjon med video og lyd",
"user_id": 1,
"time_from": "11.04.2017 13:00:00",
"time_to": "11.04.2017 17:00:00",
"created_at": "2017-04-03 17:12:37",
"updated_at": "2017-04-03 17:12:37",
"programs": [
  {
      "id": 1,
    "event_id": 3,
    "user_id": 2,
    "role_id": 1,
    "created_at": null,
    "updated_at": null,
    "role": {
      "id": 1,
      "name": "Camera operator",
      "description": "Operates ordinary cameras or PTZ cameras",
      "created_at": "2017-03-20 20:11:06",
      "updated_at": "2017-03-20 20:11:06",
      "programs": [
        {
            "id": 1,
          "event_id": 3,
          "user_id": 2,
          "role_id": 1,
          "created_at": null,
          "updated_at": null,
          "user": {
            "id": 2,
            "name": "Dummy Dum",
            "email": "dummy@example.com",
            "created_at": "2017-03-20 16:45:09",
            "updated_at": "2017-03-20 16:45:09"
          }
        },
        {
            "id": 2,
          "event_id": 2,
          "user_id": 2,
          "role_id": 1,
          "created_at": null,
          "updated_at": null,
          "user": {
            "id": 2,
            "name": "Dummy Dum",
            "email": "dummy@example.com",
            "created_at": "2017-03-20 16:45:09",
            "updated_at": "2017-03-20 16:45:09"
          }
        }
      ]
    }
  }
]
}

I can't get the models to relate to eachother - it seems. The preferred result that I want is that all the Events is tied with many users - and all the users for that event to be tied to one role. How can i accomplish this with Laravel and Eloquent?

Thanks for any responses!

EDIT: To fetch the data i use the following code to generate the results above

$events = Event::with('programs.role.programs.user')->get();

Content of the programs table

# id, event_id, user_id, role_id, created_at, updated_at
'1', '3', '2', '1', NULL, NULL
'2', '2', '2', '1', NULL, NULL

This would mean that the user with an ID of 2 is only associated with event 3 with an role of 1 and event 2 with a role of 1. As you can see from the results both events has both role 1 and 2. Sorry for bad explanation..



via Fredrik Angell Moe

Advertisement