Search code examples
laraveleloquent-relationship

can't fetch data from eloquent relationships


I try to fetch specific users who sent to the auth a message using the eloquent relationships

this is the message modal

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Message extends Model
{
    
    protected $guarded = [];
    public function fromContact()
    {
        return $this->hasOne(User::class, 'id', 'from');
    }
}

and this is the message Migration

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateMessagesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('messages', function (Blueprint $table) {
            $table->bigIncrements('id');
        $table->integer('from')->unsigned();
            $table->integer('to')->unsigned();
            $table->text('text');
            $table->text('img')->nullable();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('messages');
    }
}

and I don't change the User modal I try to use the where() function but didn't work


Solution

  • I believe you're misusing eloquent relationships.

    One To Many

    A one-to-many relationship is used to define relationships where a single model is the parent to one or more child models.

    Try this instead.

    // User model.
    class User extends Authenticatable
    {
    // ...
        public function sentMessages()
        {
            return $this->hasMany(Message::class, 'from', 'id');
        }
        public function receivedMessages()
        {
            return $this->hasMany(Message::class, 'to', 'id');
        }
    }
    
    // Message model.
    class Message extends Model
    {
        use HasFactory;
        public function fromContact()
        {
            return $this->belongsTo(User::class, 'from', 'id');
        }
    
        public function toContact()
        {
            return $this->belongsTo(User::class, 'to', 'id');
        }
    }
    
    // Message create table migration.
    class CreateMessagesTable extends Migration
    {
        /**
         * Run the migrations.
         *
         * @return void
         */
        public function up()
        {
            Schema::create('messages', function (Blueprint $table) {
                $table->id();
                $table->unsignedBigInteger('from');
                $table->unsignedBigInteger('to');
                $table->text('text');
                $table->text('img')->nullable();
                $table->timestamps();
    
                $table->foreign("from")
                    ->references("id")
                    ->on("users")
                    ->onDelete("cascade");
    
                $table->foreign("to")
                    ->references("id")
                    ->on("users")
                    ->onDelete("cascade");
            });
        }
    
        /**
         * Reverse the migrations.
         *
         * @return void
         */
        public function down()
        {
            Schema::dropIfExists('message');
        }
    }
    
    // Sample query
    App\Models\Message::find(1)->with("fromContact", "toContact")->first();
    
    // Sample output.
    /*
    => App\Models\Message {#4322
         id: 1,
         from: 2,
         to: 3,
         text: "foo",
         img: null,
         created_at: null,
         updated_at: null,
         fromContact: App\Models\User {#4338
           id: 2,
           name: "stevenmwesigwa",
           email: "jwaters@gmail.com",
           email_verified_at: null,
           created_at: "2021-05-14 15:27:35",
           updated_at: "2021-05-14 15:27:35",
         },
         toContact: App\Models\User {#4339
           id: 3,
           name: "john ripper",
           email: "steven.mwesigwa@f.com",
           email_verified_at: null,
           created_at: "2021-05-14 15:30:18",
           updated_at: "2021-05-14 15:30:18",
         },
       }
    */
    
    // Sample query 2.
    App\Models\User::with(
        [
            "sentMessages" => function($query){
            $query->with("fromContact", "toContact");
        }])
        ->where("id", 2)
        ->first();
    
    // Sample output 2.
    /*
    => App\Models\User {#4357
         id: 2,
         name: "stevenmwesigwa",
         email: "jwaters@gmail.com",
         email_verified_at: null,
         created_at: "2021-05-14 15:27:35",
         updated_at: "2021-05-14 15:27:35",
         sentMessages: Illuminate\Database\Eloquent\Collection {#4369
           all: [
             App\Models\Message {#4363
               id: 1,
               from: 2,
               to: 3,
               text: "foo",
               img: null,
               created_at: null,
               updated_at: null,
               fromContact: App\Models\User {#4343
                 id: 2,
                 name: "stevenmwesigwa",
                 email: "jwaters@gmail.com",
                 email_verified_at: null,
                 created_at: "2021-05-14 15:27:35",
                 updated_at: "2021-05-14 15:27:35",
               },
               toContact: App\Models\User {#4380
                 id: 3,
                 name: "john ripper",
                 email: "steven.mwesigwa@f.com",
                 email_verified_at: null,
                 created_at: "2021-05-14 15:30:18",
                 updated_at: "2021-05-14 15:30:18",
               },
             },
             App\Models\Message {#4372
               id: 2,
               from: 2,
               to: 4,
               text: "bar",
               img: null,
               created_at: null,
               updated_at: null,
               fromContact: App\Models\User {#4343
                 id: 2,
                 name: "stevenmwesigwa",
                 email: "jwaters@gmail.com",
                 email_verified_at: null,
                 created_at: "2021-05-14 15:27:35",
                 updated_at: "2021-05-14 15:27:35",
               },
               toContact: App\Models\User {#4382
                 id: 4,
                 name: "denis parter",
                 email: "ajoluvya@gmail.com",
                 email_verified_at: null,
                 created_at: "2021-05-14 16:16:29",
                 updated_at: "2021-05-14 16:16:29",
               },
             },
           ],
         },
       }
    */