TimeSocks's avatar

Defining a table's relationship ... to itself

I have an Events table containing event information, and I want to show a list of related events. I have a table consisting of the Event Ids and a 'Related' Id, which is of course simply the Id of another event.

Each event can have many related events. I am going around in circles trying to work out how to relate them though. How can I do it?

0 likes
23 replies
mstnorris's avatar
public function related()
{
    return $this->hasMany('Event', 'related_id'); // or whatever your Related ID field is called.
}
TimeSocks's avatar

@mstnorris can't seem to get that to work. Perhaps I'm querying it wrong, but it keeps on looking for 'related_id' in my 'Events' table, which naturally doesn't have that column.

RachidLaasri's avatar
public function related()
{
    return $this->hasMany('Event', 'your_field_name_here');
}

If you still getting an error, show us your code.

TimeSocks's avatar

@RachidLaasri I've tried that. I'm assuming it goes in the RelatedEvents model? How should I then access the related events in my query?

RachidLaasri's avatar

You don't need two models, only one will do the trick. assuming your Events table schema looks something like this

id
... // other columns
related_to //  the column that determines which event this belongs to 

Add this method to your Even model

public function related()
{
    return $this->hasMany('Event', 'related_to');
}

And you can get all the related events using :

$event = Even::findOrFail(1); // find the event with the id of 1.
$relatedEvents = $event->related; // get the related events.
RachidLaasri's avatar

Okay, so create another model named "RelatedEvents" for example and add this this to your "Event" model :

public function related()
{
    return $this->hasMany('App\RelatedEvents', 'related');
}
TimeSocks's avatar

@RachidLaasri Yeah, that's what I've done as per @mstnorris suggestion. However, if I say:

$event = Event::find(1)
$related = $event->related()->get()

I just get the ID of the related course - I want the name of the course referred to by that ID.

mstnorris's avatar
$event = Event::find(1);
$relatedId = $event->related()->get();
$relatedEvent = Event::find($relatedId)->get();
$relatedEvent->name;
TimeSocks's avatar

@mstnorris but that won't work because $relatedId is an array consisting of event_id and rel_id...

mstnorris's avatar

@TimeSocks you can do this, and then you will have multiple events to which you can get the name etc

$event = Event::find(1);
$relatedIds = $event->related()->get();
$events = DB::table('events')
                    ->whereIn('related_id', $relatedIds)->get();
TimeSocks's avatar

@mstnorris

Class 'App\Http\Controllers\DB' not found

This seems to be getting real complicated for something that's a simple join in vanilla PHP/SQL...

mstnorris's avatar

Add the following to the top of your Controller.

use Illuminate\Support\Facades\DB;
TimeSocks's avatar

@mstnorris

ErrorException in Grammar.php line 111: Argument 1 passed to Illuminate\Database\Grammar::parameterize() must be of the type array, object given,

I guess it's actually an object not an array...

:)

RachidLaasri's avatar

The problem here is on your database design, you could have solved this with just few lines and i explained on my second comment.

However, if you wanna go with that solution, change the 2rd line :

$relatedIds = $event->related()->get()->toArray();
TimeSocks's avatar

@RachidLaasri

If I make the related events part of the events table, that means I can only have one related event. I need to be able to have multiple related events.

@mstnorris

I have an event page. Any one event can have other related events, like an Amazon product might have a 'customers also bought this' section. I just want to be able to list (and link to) the related events for any given event.

In SQL, I just have to do:

SELECT e.event_name, e.event_id, r.rel_id
               FROM events AS e
               INNER JOIN relatedevents AS r ON e.event_id = r.rel_id
               WHERE r.event_id = 1

Then loop through the results to output. I essentially need to do that, in Laravel.

TimeSocks's avatar

@mstnorris because I'm working with a pre-existing database. It seems odd to have all the other site data in a MySQL database but to have one section in a JSON string. Unless I'm completely missing your point...

mstnorris's avatar

You store the JSON string in the database. Watch the two lessons I just linked to, and you'll get there.

arabsight's avatar

try this:

$event = Event::find(1);
$relatedIds = $event->related()->lists('related_id');
$events = Event::whereIn('related_id', $relatedIds)->get();
bek_dev's avatar

public function children() { return $this->hasMany(Category::class, 'parent_id'); }

martinbean's avatar

@bek_dev Thanks for creating an account just to reply to a thread that is literally a decade old…

Please or to participate in this conversation.