简体   繁体   中英

Laravel belongsTo and hasMany not returning data

I'm new to laravel/eloquent and so far very much enjoying them, but I'm having trouble getting belongsTo and hasMany working. I've read through countless issues others have had and haven't found a solution that solves it for me.

I have a "Page" model and a "Category" model. Here is the definition for the tables:

Schema::create('pages', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
    $table->timestamps();
});

Schema::create('categories', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('page_id');
    $table->foreign('page_id')->references('id')->on('pages');
    $table->string('name');
    $table->timestamps();
});

Here is my Page model:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Page extends Model
{
    public function categories()
    {
        return $this->hasMany('App\Category');
    }
}

Here is my Category model:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    public function page() 
    {
        return $this->belongsTo('App\Page');
    }
}

Here are the results from some tinkering:

> php artisan cache:clear
Application cache cleared!
> php artisan tinker
>>> \App\Category::find(1)
=> App\Category {#2916
     id: "1",
     page_id: "1",
     name: "First Category",
     created_at: "2018-12-30 03:18:07.347",
     updated_at: "2018-12-30 03:18:07.347",
   }
>>> \App\Category::find(1)->page()
=> Illuminate\Database\Eloquent\Relations\BelongsTo {#2918}
>>> \App\Page::find(1)
=> App\Page {#2902
     id: "1",
     name: "First Page",
     created_at: "2018-12-30 03:18:07.220",
     updated_at: "2018-12-30 03:18:07.220",
   }
>>> \App\Page::find(1)->categories()
=> Illuminate\Database\Eloquent\Relations\HasMany {#2922}
>>>

I'm getting my objects just fine, but when I try to pull the relationship I'm just getting what seem like null objects:

=> Illuminate\\Database\\Eloquent\\Relations\\BelongsTo {#2918}

=> Illuminate\\Database\\Eloquent\\Relations\\HasMany {#2922}

If I swap out my page() and categories() functions for ones like these all works well:

public function page() 
{
    return \App\Page::find($this->page_id);
}

public function categories()
{
    return \App\Category::where('page_id', $this->id)->get();
}

Here are those results:

> php artisan cache:clear
Application cache cleared!
> php artisan tinker
Psy Shell v0.9.9 (PHP 7.3.0 — cli) by Justin Hileman
>>> \App\Page::find(1)
=> App\Page {#2916
     id: "1",
     name: "First Page",
     created_at: "2018-12-30 03:18:07.220",
     updated_at: "2018-12-30 03:18:07.220",
   }
>>> \App\Page::find(1)->categories()
=> Illuminate\Database\Eloquent\Collection {#2918
     all: [
       App\Category {#2921
         id: "1",
         page_id: "1",
         name: "First Category",
         created_at: "2018-12-30 03:18:07.347",
         updated_at: "2018-12-30 03:18:07.347",
       },
       App\Category {#2922
         id: "2",
         page_id: "1",
         name: "Second Category",
         created_at: "2018-12-30 03:18:07.480",
         updated_at: "2018-12-30 03:18:07.480",
       },
       App\Category {#2923
         id: "3",
         page_id: "1",
         name: "Third Category",
         created_at: "2018-12-30 03:18:07.623",
         updated_at: "2018-12-30 03:18:07.623",
       },
     ],
   }
>>> \App\Category::find(1)
=> App\Category {#2904
     id: "1",
     page_id: "1",
     name: "First Category",
     created_at: "2018-12-30 03:18:07.347",
     updated_at: "2018-12-30 03:18:07.347",
   }
>>> \App\Category::find(1)->page()
=> App\Page {#2921
     id: "1",
     name: "First Page",
     created_at: "2018-12-30 03:18:07.220",
     updated_at: "2018-12-30 03:18:07.220",
   }
>>>

EDIT:

I found if I add ->get() I see the data while tinkering as I was expecting:

public function page() 
{
    return $this->belongsTo('App\Page')->get();
}

However, none of the examples I've seen show anyone doing this. Am I just misunderstanding how this is supposed to work? I would expect while tinkering just doing $page->categories(); would give me the categories without needing to do $page->categories()->get();

Try this.

    Schema::create('categories', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('page_id')->unsigned();
    $table->foreign('page_id')->references('id')->on('pages');
    $table->string('name');
    $table->timestamps();
});

Ah, as usual I found this to be a simple fix.

Calling $page->categories as a property gives me the data

Calling $page->categories() as a function returns an object I can continue chaining further commands to.

In case it helps anyone, I found the solution by revisiting the extremely helpful laracasts videos. Specifically the episode on eloquent relationships where what I just posted is clearly explained: https://laracasts.com/series/laravel-from-scratch-2018/episodes/16

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM