Search code examples
laraveleloquentforeign-keysrelationshipmass-assignment

Model returns relation´s dynamic attributes but null relation


I have set 2 models (Post and Category) with it´s proper relationships configured

class Post extends Model
{
    protected $fillable = [
        'title',
        'excerpt',
        'body',
        'featured',
        'published',
        'category_id',
    ];

    public function category()
    {
        return $this->belongsTo('App\Category');
    }
}

class Category extends Model
{
    protected $fillable = [
        'name',
    ];

    public function posts()
    {
        return $this->hasMany('App\Post');
    }
}

And my Post´s storing method is

public function store(Request $request)
{
    $post = Post::create($request->all());
    return redirect('admin/posts');
}

The thing is, it´s actually working ok, it sets the category_id on the table and I can fetch all the dynamic data by using $post->category->name, but when I var_dump($post->relation) I get a null return.

I if create a new Post model, set all the attributes, save it and then associate the Category model (as documented on the official channel), it will return everything as expected.

For now, all I need is to fetch it´s dynamic attributes, and it´s working fine now, but I know I must be doing something wrong to get the null response. My concern is that it may be working fine now, but when the project gets larger I´ll probably face a bigger problem and I´ll have a lot of work to fix this issue.


Solution

  • The relation isn't there because you haven't loaded it. All it knows is the foreign key. It would be wildly inefficient if it grabbed all that information for you because it wouldn't always need all that. Think of instances where a single model could have many relationships, that would be many database calls for no reason.

    If you need the relation, you can use $post->category. Since the relation is not yet loaded, it will get it for you when you do this.

    Or you can eager load it by using the following $post->load('category') although this doesn't really benefit you because you are working with a single Post at this point. If you had a collection of Post objects, then you'd start seeing the benefits of using $posts->load('category') otherwise you end up with the n + 1 problem.

    Consequently, if you use $post->load('category') and then var_dump($post), you should see that the relation is no longer null.