Laravel: hasMany Relationship is null / empty

10,949

The method that creates the relationship has to return a value, this is what I am saying:

Rather than:

public function keys()
{
    $this->hasMany('App\Models\Game\Key', 'id', 'game_id');
}

You should have:

public function keys()
{
    return $this->hasMany('App\Models\Game\Key', 'id', 'game_id');
}

The difference is the return statement, your methods that create the relationship do not return any, they should return the results of the hasOne and hasMany for all method that uses them for query building.

PS: You should add the return statement for the other methods that create a relationship.

Share:
10,949
festie
Author by

festie

I'm a young software developer from germany.

Updated on June 13, 2022

Comments

  • festie
    festie almost 2 years

    my problem is, that my hasMany relationship returns just an "empty" collection:

    Collection {#172 ▼
      #items: array:1 [▼
        0 => 0
      ]
    }
    

    My belongsTo relationship just returns "null".

    Here are the eloquents: Game.php

    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Model;
    
    /**
     * App\Models\Game
     *
     * @property integer $id
     * @property integer $steamid
     * @property string $name
     * @property \Carbon\Carbon $created_at
     * @property \Carbon\Carbon $updated_at
     */
    class Game extends Model
    {
        protected $fillable = [
            'appid', 'name'
        ];
    
        public function keys()
        {
            $this->hasMany('App\Models\Game\Key', 'id', 'game_id');
        }
    }
    
    Key.php
    <?php
    
    namespace App\Models\Game;
    
    use Illuminate\Database\Eloquent\Model;
    
    /**
     * App\Models\Game\Key
     *
     */
    class Key extends Model
    {
        protected $fillable = [
            'key', 'game_id', 'author_id',
        ];
    
        public static function getRandom()
        {
            if (!self::available()) return false;
            $keys = Key::where('redeemer_id', 0)->get();
            $key = $keys[ rand(0, count($keys) - 1) ];
            return $key;
        }
    
        public static function available()
        {
            $keys = Key::where('redeemer_id', 0)->get();
            $count = count($keys);
            if ($count > 0) return $count;
            return false;
        }
    
        public function author()
        {
            $this->hasOne('App\Models\User', 'author_id');
        }
    
        public function redeemer()
        {
            $this->hasOne('App\Models\User', 'redeemer_id');
        }
    
        public function game()
        {
            $this->belongsTo('App\Models\Game', 'game_id');
        }
    }
    
    User.php
    <?php
    
    namespace App\Models;
    
    use Carbon\Carbon;
    use Illuminate\Foundation\Auth\User as Authenticatable;
    
    /**
     * App\Models\User
     *
     * @property integer $id
     * @property string $name
     * @property string $email
     * @property string $password
     * @property string $remember_token
     * @property \Carbon\Carbon $created_at
     * @property \Carbon\Carbon $updated_at
     */
    class User extends Authenticatable
    {
        protected $fillable = [
            'username', 'email', 'password'
        ];
    
        protected $hidden = [
            'password', 'remember_token',
        ];
    
        public function keys()
        {
            $this->hasMany('App\Models\Game\Key');
        }
    
        public function canRedeem()
        {
            // TODO: not tested yet
            if(count(self::keys()) == 0) return true;
            if(Carbon::now(-24) > self::keys()->first()->created_at) return true;
                return false;
        }
    }
    

    these are my migrations:

    user-table
    <?php
    
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Database\Migrations\Migration;
    
    class CreateUsersTable extends Migration
    {
        /**
         * Run the migrations.
         *
         * @return void
         */
        public function up()
        {
            Schema::create('users', function (Blueprint $table) {
                $table->increments('id');
                $table->string('username')->unique();
                $table->string('email')->unique();
                $table->string('password', 60);
                $table->rememberToken();
                $table->timestamps();
            });
        }
    
        /**
         * Reverse the migrations.
         *
         * @return void
         */
        public function down()
        {
            Schema::drop('users');
        }
    }
    
    game-table
    <?php
    
    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;
    
    class CreateGamesTable extends Migration
    {
        /**
         * Run the migrations.
         *
         * @return void
         */
        public function up()
        {
            if (!Schema::hasTable('games')) {
                Schema::create('games', function (Blueprint $table) {
                    $table->increments('id');
    
                    $table->integer('appid')->unsigned();
                    $table->string('name');
    
                    $table->timestamps();
                });
            }
        }
    
        /**
         * Reverse the migrations.
         *
         * @return void
         */
        public function down()
        {
            //Schema::drop('games');
        }
    }
    
    keys-table
    <?php
    
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Database\Migrations\Migration;
    
    class CreateKeysTable extends Migration
    {
        /**
         * Run the migrations.
         *
         * @return void
         */
        public function up()
        {
            Schema::create('keys', function(Blueprint $table) {
                $table->increments('id');
    
                $table->string('key');
    
                $table->integer('game_id')->unsigned()->index();
                $table->foreign('game_id')->references('id')->on('games')->onDelete('cascade');
    
                $table->integer('author_id')->unsigned()->index();
                $table->integer('redeemer_id')->unsigned()->index();
    
                $table->timestamps();
    
    
            });
        }
    
        /**
         * Reverse the migrations.
         *
         * @return void
         */
        public function down()
        {
            Schema::drop('keys');
        }
    }
    

    I googled alot and I found some "solutions" on Laracast, but they only tell me what I already have.

    Can anyone help? Deazl

  • festie
    festie about 8 years
    Thanks! Didn't recognized that I missed that. Now its working :)
  • Agu V
    Agu V over 7 years
    Hours because of this simple mistake. Thanks!
  • Luís Almeida
    Luís Almeida about 6 years
    I still have the problem and I have the return statement there.