Home > Back-end >  Why does hasOne and BelongTo relationships load only ids but not the models
Why does hasOne and BelongTo relationships load only ids but not the models

Time:06-08

I've got a problem with relations in Laravel 9.14 Eloquent.

I have two models File and Project with coresponding tables in MySql database files and projects.

Project migration

Schema::create('projects', static function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->string('code');
        $table->string('theme');
        $table->foreignId('discipline_id')->constrained('disciplines');
        $table->foreignId('user_id')->constrained('users');
        $table->string('external_id');
        $table->foreignId('preview')->nullable()->constrained('files');
        $table->date('publish_date');
        $table->timestamps();
    });

File migration

Schema::create('files', static function (Blueprint $table) {
        $table->id();
        $table->string('original_name');
        $table->string('extension');
        $table->string('mime_type');
        $table->integer('size')->unsigned();
        $table->timestamps();
    });

Project has field which is related to the File model called 'preview'. Project, basically can have only one preview file. So I did these relatioins in models:

class Project extends Model


public function preview(): BelongsTo
{
    return $this->belongsTo(File::class, 'preview', 'id');
}

class File extends Model

public function previewProject(): HasOne
{
    return $this->hasOne(Project::class, 'preview', 'id');
}

When i try to get preview of a project this way (controller method):

public function index(): Factory|View|Application
{
    $userId = auth()->user()->id;
    $projects = User::find($userId)->projects()->with(['user', 'preview'])->get();

    //dd($projects->first()->user);
    ddd($projects->first()->preview);

    return view('user.index', [
        'projects' => $projects
    ]);
}

Instead of File model object I get only integer id of File. Queries, however, look right: queries image

Can somebody tell me what is the problem here? I've stuck badly for couple of days on this one...

CodePudding user response:

There is no error, the integer your are getting is the value of the attribute but by "chance" both your attribute and relation have the same name.

Either change the relation name:

class Project extends Model

public function previewFile(): BelongsTo
{
    return $this->belongsTo(File::class, 'preview', 'id');
}
public function index(): Factory|View|Application
{
    $projects = auth()->user()->projects()->with(['user', 'previewFile'])->get();

    //dd($projects->first()->user);
    ddd($projects->first()->previewFile);

    return view('user.index', [
        'projects' => $projects
    ]);
}

Or change the attribute name

Schema::create('projects', static function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->string('code');
        $table->string('theme');
        $table->foreignId('discipline_id')->constrained('disciplines');
        $table->foreignId('user_id')->constrained('users');
        $table->string('external_id');
        $table->foreignId('preview_id')->nullable()->constrained('files');
        $table->date('publish_date');
        $table->timestamps();
    });
class Project extends Model

public function preview(): BelongsTo
{
    return $this->belongsTo(File::class, 'preview_id', 'id');
}
  • Related