Yosef
Yosef

Reputation: 442

Laravel BelongsTo returning empty object

I have a table called messages and users. the users is the default users table generated by laravel auth. for some reason in my postMessage function in my controller when i try the return

return response()->json(['s' => $broadcastMessage, 'r' => $broadcastMessage->MessageOwner()]);

the relationship ship returns an empty object. i know that the MessageOwner relationship works because i use it in a different function and it works fine but i can't figure out why it wont work here? I made sure and it stores the user_id and it's the correct id.

Note that it does return the message.

here is migration up function

Schema::create('messages', function (Blueprint $table) {
            $table->bigIncrements('id');

            $table->bigInteger('user_id')->unsigned()->index();
            $table->foreign('user_id')->references('id')->on('users');

            $table->longText('message');

            $table->timestamps();
        });

here is my message model

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Message extends Model
{
    protected $table = 'messages';
    protected $fillable = [
        'user_id', 'message'
    ];

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

    public function MessageOwner()
    {
        return $this->belongsTo(User::class, 'user_id', 'id');
    }

    public function job()
    {
        return $this->belongsToMany(Job::class);
    }
}

and here is my controller function

public function postMessage(Request $request)
    {
        try {
            $message = Message::create([
                'user_id' => $request->input('user_id'),
                'message' => $request->input('message')
            ]);

            $job = Job::find($request->input('job_id'));
            $job->messages()->attach($message);

            $broadcastMessage = Message::find($message->id);

            return response()->json(['s' => $broadcastMessage, 'r' => $broadcastMessage->MessageOwner()]);

            event(new MessagePushed($broadcastMessage));

            return response()->json([
                'success' => true,
                'message' => 'success',
            ]);

        } catch (\Exception $exception) {
            return response()->json([
                'success' => false,
                'error' => true,
                'message' => $exception->getMessage()
            ], 500);
        }
    }

Upvotes: 1

Views: 1351

Answers (2)

Samuel Isirima
Samuel Isirima

Reputation: 29

If you want to get the Model Object associated with the relationship, do not add the parenthesis when calling the method name.

If you have 2 models defined like so;

<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class StylistPasswordRecovery extends Model
{
    use HasFactory;
    protected $fillable = ['token', 'stylist_id', 'stylist_email', 
    'expires'];
    protected $table = "stylists_password_recovery";


    public function stylist()
    {
        return $this->belongsTo(Stylist::class, 'stylist_id');
    }
}

?>

<?php

namespace App\Models;
use App\Models\Appointment;
use Laravel\Sanctum\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use PHPOpenSourceSaver\JWTAuth\Contracts\JWTSubject;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Foundation\Auth\User as Authenticatable;

class Stylist extends Authenticatable implements JWTSubject
{
    use HasApiTokens, HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'first_name',
        'last_name',
        'gender',
        'phone',
        'email',
        'password',
        'work_name'
    ];

    protected $guard = "stylist";

    public function password_recoveries()
    {
        return $this->hasMany(StylistPasswordRecovery::class);
    }
}

If you want to access the stylist object from a password recovery instance, this is how you do it;

    $stylist = $stylistPasswordRecovery->stylist;

As opposed to doing

    $stylist = $stylistPasswordRecovery->stylist(); //this is wrong

Upvotes: 0

Elias Soares
Elias Soares

Reputation: 10264

You are calling the relationship method, not the it's value.

Try without the ():

return response()->json(['s' => $broadcastMessage, 'r' => $broadcastMessage->MessageOwner]);

Also you should consider using lower_snake_case for all your relationship methods and name the foreign key by relationshio_name_id, so you don't need to manually define the foreign key name, Laravel will automatically guess it.

Upvotes: 3

Related Questions