Reputation: 731
I'm new to laravel and have to define relationships for 3 tables. The tables are events, categories, packages.
Event can have multiple categories and each category can have multiple packages. Same categories can be in various events.
So far i have following tables but not sure if i'm taking the right approach:
Table:events
id - int
title - varchar ...
Table: categories
id - int
name - varchar
Table:packages
id - int
name - varchar
price - decimal
Table:category_package
category_id - int
package_id - int
Table:event_package
event_id - int
package_id - int
Inside package model I have:
public function categories()
{
return $this->belongsToMany('\App\Category');
}
public function events()
{
return $this->belongsToMany('\App\Event');
}
Inside event and category model i have:
public function packages()
{
return $this->belongsToMany('\App\Package');
}
I'd like to get the following result out when i query for specific event with its relationships:
[
"events" => [
"id" => 1,
"title" => "whatever title",
"categories" => [
[
"id" => 1,
"name" => "the category",
"packages" => [
["id" => 1, "name" => "pack1"],
["id" => 2, "name" => "pack2"],
["id" => 3, "name" => "pack3"]
]],
[
"id" => 2,
"name" => "second cat",
"packages" => [
["id" => 4, "name" => "pack4"],
["id" => 5, "name" => "pack5"],
["id" => 6, "name" => "pack6"]
]],
]
]
]
Is this possible in laravel and how would i go about it. I'm pretty sure I didn't take correct approach.
Thanks
Upvotes: 3
Views: 3769
Reputation: 7899
Based on your table structure and your comments, it seems like you want this setup:
Event
has multiple Packages
Package
belongs to one Event
Category
has multiple Packages
Package
belongs to one Category
You don't need the pivot tables (category_package
and event_package
) so remove those. Then your packages
table needs to have an event_id
and category_id
field added to it.
Table:packages
id - int
name - varchar
price - decimal
event_id - int
category_id - int
You should setup your models like this:
class Event extends Model {
public function packages() {
return $this->hasMany('App\Package');
}
}
class Category extends Model {
public function packages() {
return $this->hasMany('App\Package');
}
}
class Package extends Model {
public function event() {
return $this->belongsTo('App\Event');
}
public function category() {
return $this->belongsTo('App\Category');
}
}
The array you are trying to get in your question can't be retrieved elegantly, you'll have to do some manual work, but it's not hard if you use eager loading with constraints.
To get one Event
and its Categories
and Packages
you would do this:
$event = Event::find($eventId); // Or however you want to get the Event
$event['categories'] = Category::with(['packages' => function($query) use($event) {
$query->where('event_id', $event->id);
}])->get();
To get multiple Events
and their Categories
and Packages
you would just use a loop and add the categories for each Event
.
$events = Event::all(); // Or however you want to get the Events
foreach ($events as $key => $event) {
$events[$key]['categories'] = Category::with(['packages' => function($query) use ($event) {
$query->where('event_id', $event->id);
}])->get();
}
Upvotes: 1