Aidanas Naugžemis
Aidanas Naugžemis

Reputation: 99

How to know when my relation returns an object and when an array?

I got few relations in my model Reply:

/** Reply.php */

public function thread()
{

    return $this->belongsTo(Thread::class);
}

public function user()
{
    return $this->belongsTo(User::class);
}

My reply table got user_id and thread_id

And then I try to get user name I do it like this:

$reply->user->name

And it works.

But when I try to get thread title:

$reply->thread->title

I got error:

Trying to get property title of non-object

And if need to get title only method I know is:

$reply->thread['title']

What is the difference between methods I use? Why in one case I get user as an object but in another I get thread as an array?


Update:

My Reply model relations:

public function user()
{
    return $this->belongsTo(User::class);
}

public function favorites()
{
    return $this->morphMany(Favorite::class, 'favorited');
}

public function thread()
{
    return $this->belongsTo(Thread::class);
}

My Thread model relations:

public function replies()
{
    return $this->hasMany(Reply::class);
}

public function user()
{
    return $this->belongsTo(User::class);
}

public function category()
{
    return $this->belongsTo(Category::class);
}

And my User model relations:

public function threads()
{
    return $this->hasMany(Thread::class)->latest();
}

public function replies()
{
    return $this->hasMany(Reply::class)->latest();
}

Upvotes: 2

Views: 356

Answers (3)

Kenny Horna
Kenny Horna

Reputation: 14281

The Model class implements the Arrayable interface, this means that you can access the attributes also as if it were an array, this is why this work:

$reply->thread['title'];

When you use a BelongsTo relationship, this expect to return an object (an instance of your model) or null in case this relation isn't set, this is why you can use "magic methods" to access attributes like this:

$reply->thread // an object
$reply->thread->title // getting attributes using magic methods

But, what happen when the relationship isn't set? well, the relationship will return null so when you do this:

$reply->thread->title

It will throw an arror:

Trying to get property title of non-object

Because you are trying to access the title attribute of null.


Update:

This is where -I think- the error is. With the newest version of Laravel (as of today: Laravel 5.8), the primmary keys types has changed from integers to bigIntegers(), and this is for all the tables:

Schema::create('replies', function (Blueprint $table)
{
    $table->bigIncrements('id'); // <---- equivalent to bigInteger
    $table->integer('user_id')->unsigned;
    $table->integer('thread_id')->unsigned;
    $table->text('body');
    $table->timestamps();
});

So, your foreign keys should be also big integers, try this:

Schema::create('replies', function (Blueprint $table)
{
    $table->bigIncrements('id');
    $table->unsignedBigInteger('user_id'); // <-----------
    $table->unsignedBigInteger('thread_id'); // <-----------
    $table->text('body');
    $table->timestamps();
});

Check this article related this issue.

Upvotes: 2

ShuBham GuPta
ShuBham GuPta

Reputation: 324

When you make

one to one

relation then relation will return object When you make

one to many

relation will return array of objects

Upvotes: 2

Florian Laforgue
Florian Laforgue

Reputation: 299

I think that the only reason for this error would be a null return from the relation. In that case

$reply->thread['title']

won't work, can you check it please ?

If the $reply->thread['title'] works, I would like to see the output of dd($reply->thread); please.

If it does not work and the cause of the error is indeed a null return, you just have to check that

$reply->thread is not null before using it.

Let me know if it helped you :)

Upvotes: 1

Related Questions