egbokalaka's avatar

Pivot table access in blade

I'm a newbie to Laravel so I'm probably making some sort of noob error. That said, here's my problem.

I'm trying to access a related table from within my blade,. Here are relevant portions of my models:

class _MeetingUser extends Model
{
 	...
    public function meeting()
    {
        return $this->belongsToMany(Meetings::class);
    }
    public function user()
    {
        return $this->belongsToMany(Users::class);
    }
}
class Meetings extends Model
{
	...
    public function users()
    {
        return $this->belongsToMany(Users::class, 'meeting__user');
    }
	...

I have this in my controller:

class MeetingController extends Controller
{
    public function edit(Request $request): View
    {
        return view('meetings.edit', [
            'meetings' => Meetings::all(),
            'secretaries' => Users::all(),
        ]);
	...

And my blade has this:

             @foreach($meetings as $meeting)
    		...
                        <td><select name="secretaries[]" id="secretaries">
                                <option value="0">Select Secretary</option>
                                @foreach($secretaries as $secretary)
                                    <option value="{{$secretary->id}}"
                                    @if($meeting->users()->id == $secretary->id)
                                        selected="selected"
                                    @endif
                                    >{{$secretary->name}}</option>
                                @endforeach
                            </select>
                        </td>
 			...

When I load the page, I get this:

Undefined property: Illuminate\Database\Eloquent\Relations\BelongsToMany::$id

Although I can see it would be wrong, the same thing occurs when I try users_id instead of id.

The pivot table works in the controller. What am I doing wrong?

0 likes
5 replies
egbokalaka's avatar

Well, this works. But it seems ugly.

  {{  $existing_secretary_id=DB::scalar('select users_id from meeting__user where meetings_id = ?',
                                [$meeting->id]);
                        }}
                        <td><select name="secretaries[]" id="secretaries">
                                <option value="0">Select Secretary</option>
                                @foreach($secretaries as $secretary)
                                    <option value="{{$secretary->id}}"
                                    @if($secretary->id == $existing_secretary_id)
                                        selected="selected"
                                    @endif
                                    >{{$secretary->name}}</option>
                                @endforeach
                            </select>
                        </td>
Forrest's avatar

@egbokalaka You could load relationships in controller or service class using 'with' method : Meeting::with('users') or vice versa User::with('meetings') and then pass the data to the view

1 like
egbokalaka's avatar

@Forrest You're right that I need to eager load the data in the controller. But my real problem is that $meetings->users()->id returns the error shown, either in the view or the controller. Consistent with that error, dd($meetings->user()) returns a Illuminate\Database\Eloquent\Relations\BelongsToMany: object. Where is the related user model? This works however: $meeting->users()->syncWithoutDetaching($secretary_id);

Bogey's avatar

You have your models set up wrong. I'm assuming you got the following models: users, meetings, meeting_user

meeting_user being the pivot table, your relationships will be set up in the users table and the meetings table.

users model

function meetings() {
        return $this->belongsToMany(Meetings::class, 'meeting_user');
}

meetings model

function users() {
        return $this->belongsToMany(Users::class, 'meeting_user');
}

You don't need to do anything in your pivot table model

And then in your controllers.

$user = User::all();

foreach($user->meetings as $meeting) {
    // my looping logic
}

$meeting = Meeting::all();

foreach($meeting->users as $user) {
    // more of my looping logic
}
egbokalaka's avatar
egbokalaka
OP
Best Answer
Level 1

I extensively rewrote this to do eager loading in the controller. As I was working through the process, I realized what the original problem was.

@if($meeting->users()->id == $secretary->id)

$meeting->users() is a collection. To extract the id, I needed $meeting->users()->first()->id; The problem stemmed from my using a many-to-many relationship between users and meetings (which I want for future changes) and expecting the user() to be a single object.

Please or to participate in this conversation.