Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel many to many relationship using Eloquent

I'm trying to create a many to many relationship using Laravel, but I am stuck.

Here's my current table model:

album

album_id
name
created_at

user_image

user_image_id
value

albumxuser_image (junction table)

albumxuser_image_id (primary key & auto increment)
album_id (FK from album)
user_image_id (FK from user_image)

I want to be able to get the album name from albumxuser_image table.

Here's what I've done so far.

Album.php model

namespace App\Models;

use Illuminate\Database\Eloquent\Model;


class Album extends Model {

    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = 'album';
    protected $primaryKey = 'album_id';

    public function AlbumxUserImage() {
        return $this->belongsToMany('AlbumxUserImage', 'albumxuser_image','album_id','user_image_id');
    }
}

routes.php (I didn't use view since I'm making a practice)

Route::get('all', function() {
    $albumxuserimage = AlbumxUserImage::all();
    foreach ($albumxuserimage->AlbumxUserImage as $getthem) {
        echo $getthem->pivot->name; // I want to get the name column of the album table.
    }
});

AlbumxUserImage.php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;


class AlbumxUserImage extends Model {

    protected $table = 'albumxuser_image';
    protected $primaryKey = 'albumxuser_image_id';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['album_id', 'user_image_id'];
}

Here's the error I get

Call to undefined method Illuminate\Database\Eloquent\Collection::AlbumxUserImage()
like image 277
salep Avatar asked Dec 19 '22 01:12

salep


1 Answers

You're trying to call AlbumxUserImage() on a Collection of models instead of on each individual model.

AlbumxUserImage::all() is returning a Collection of models, which you can think of as an array. You need to iterate over the collection and call AlbumxUserImage() on each model in the collection.

That may solve your problem for now, but you seem to not understand how many-to-many relationships work in Laravel.

How you should be doing Many-To-Many

I don't know why you have a model for your pivot table. That is not how Laravel normally handles models with many-to-many relationships. A typical many-to-many relationship with your tables would look like this:

Models:

class Album extends Model {
    protected $table = 'album';
    protected $primaryKey = 'album_id';

    public function images() {
        return $this->belongsToMany('App\UserImage', 'albumxuser_image','album_id','user_image_id');
    }
}

class UserImage extends Model {
    protected $table = 'user_image';
    protected $primaryKey = 'user_image_id';

    public function albums() {
        return $this->belongsToMany('App\Album', 'albumxuser_image','user_image_id','album_id');
    }
}

Usage:

// Get all album names through UserImage
$userImages = UserImage::all();
foreach ($userImages as $userImage) {
    foreach ($userImage->albums as $album) {
        echo $album->name;
    }
}

// Get all images through Album
$albums = Album::all();
foreach ($albums as $album) {
    foreach ($album->images as $image) {
        echo $image->value;
    }
}
like image 81
BrokenBinary Avatar answered Jan 09 '23 06:01

BrokenBinary