user860511
user860511

Reputation:

Accessing and displaying pivot table data

Theory:

Users can attend many events and many events can be attended by many users. Therefore, I have two many-to-many relationships within my models, linking to a pivot table (event_user). On attending each event, I want to be able to access the pivot table data (event_user) to see if they're already attending.

event_user: --id --event_id --user_id

For example, my seed data is:

user 1 attending both event 2 and 3. I want to be able to show this within a view.

The closest I have got is (logically):

public function index()
{
    $id = Auth::user()->id;
    $attending = myApp\Event::find($id)->event;
    var_dump($attending); **But this var_dump returns NULL, but $id returns the correct ID.**

    $events = myApp\Event::all();
    $this->layout->content = View::make('events.index')->with('events', $events);
}

My aim is to disable the 'attend' button, on any event where they are already attending, only leaving the attend-able events available!

Any help would be hugely appreciated. Thank you in advance.

Any additional code which you may find necessary:

Events Model:

<?php

namespace myApp;
use Eloquent;

class Event extends Eloquent {

    public function consultant()
    {
        return $this->belongsToMany('myApp\Consultant');
    }

    public function location()
    {
        return $this->belongsToMany('myApp\Location');
    }

    public function user()
    {
        return $this->belongsToMany('myApp\User');
    }

}

User Model:

<?php

namespace myApp;
use Eloquent;

use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;

class User extends Eloquent implements UserInterface, RemindableInterface {

    public function event()
    {
        return $this->belongsToMany('Event');
    }

    public function practice()
    {
        return $this->belongToMany('Practice');
    }

index.blade.php (showing the event list)

<div class="panel panel-success">
  <!-- Default panel contents -->
  <div class="panel-heading"><strong>Events</strong></div>
  <!-- <div class="panel-body">
  </div> -->

  <!-- Table -->
  <table class="table">
    <thead>
    <tr>
        <th>Title</th>
        <th>Date</th>
        <th>Presenter</th>
        <th>Location</th>
        <th></th>
    </tr>
    </thead>
    <tbody>
        @foreach($events as $event)
        <tr>
            <td>{{ $event->title }}</td>
            <td>{{ date("j F Y", strtotime($event->date)) }}</td>
            <td>{{ $event->consultant()->first()->title }} {{ $event->consultant()->first()->surname }}</td>
            <td>{{ $event->location()->first()->address_1 }}</td>
            <td><button type="button" class="btn btn-info">Attend</button></td>
        </tr>
        @endforeach
    </tbody>
  </table>
</div>

</table>

Upvotes: 3

Views: 2107

Answers (1)

ollieread
ollieread

Reputation: 6291

I think you're going about this the wrong way, that or I have misunderstood.

Firstly, you're trying to find an event with the same primary key as the currently authenticated user, which isn't correct, although it's an easy hole to fall down.

$id = Auth::user()->id;
$attending = myApp\Event::find($id)->event; 
// equivalent of: SELECT * FROM `events` WHERE `id` = ?

Instead you'll want to do this

$id = Auth::user()->id;
$attending = myApp\Event::where('user_id', $id)->get(); 
// equivalent of: SELECT * FROM `events` WHERE `user_id` = ? (user_id insted of events.id)

That being said, surely the user events can be accessed by just calling the event property on the auth user?

$user = Auth::user();
$attending = $user->event;

To take this one step further, and make it so that you can check inside the foreach loop, you could advanced the above code to look like the following

$user = Auth::user();
$attending = $user->event->lists('id');

This will make an array of ids from the returned events that you need to assign to the view

$this->layout->content = View::make('events.index', array('events' => $events, 'attending' => $attending));

Now you can freely access it in your foreach

@foreach($events as $event)
<tr>
    <td>{{ $event->title }}</td>
    <td>{{ date("j F Y", strtotime($event->date)) }}</td>
    <td>{{ $event->consultant()->first()->title }} {{ $event->consultant()->first()->surname }}</td>
    <td>{{ $event->location()->first()->address_1 }}</td>
    <td>
    @if (!in_array($event->id, $attending))
        <button type="button" class="btn btn-info">Attend</button>
    @endif
    </td>
</tr>
@endforeach

Also, seeing as Event is a reserved Alias (unless you've modified the config, which I wouldn't recommend), you'll want to specify the namespace in the relationship declaration within User

public function event()
{
    return $this->belongsToMany('myApp\Event');
}

As a final point, it's not an issue as such, but in my own code I try to name relationships that have the potential to return multiple objects in the plural, so it would be public function events();.

Upvotes: 2

Related Questions