Search code examples
phplaravelrelational-databaselaravel-8one-to-one

How to get result of one to one relationship


I'm using Laravel 8 to make a basic online ordering system.

And in this project, every order is submitted within a user of the user who has signed in.

enter image description here

So there is a One To One relationship between users table and orders table.

Therefore, I have added these to the Models:

Order.php:

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

User.php:

public function order()
    {
        return $this->belongsTo(Order::class);
    }

Now in order to get the result of the table for showing the user name of the person who had ordered, I coded this at the Controller:

public function awaiting()
    {
        $orders = Order::with('user')->where('user_id', '!=', NULL)->latest()->paginate(20);
        return view('admin.orders.awaiting', compact('orders'));
    }

Then at the Blade:

@foreach($orders as $order)
<tr>
    <td>{{ $order->user->name }}</td>
    <td>{{ $order->description }}</td>
    <td>{{ $order->dimensions }}</td>
    <td>{{ $order->color }}</td>
    <td>{{ $order->material }}</td>
    <td>{{ $order->title }}</td>
    <th scope="row">{{ ++$menuCounter }}</th>
</tr>
@endforeach

But this is wrong because it searching for order_id at users table (which does not exist).

So the question is, how can I show the user name of the user who has ordered based on the user_id stored in orders table.

UPDATE #1:

Orders Migration:

Schema::create('orders', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->string('material');
            $table->string('color');
            $table->string('dimensions');
            $table->string('description')->nullable();
            $table->tinyInteger('user_id')->unsigned()->nullable();
            $table->timestamps();
        });

Users Migration:

public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->tinyInteger('adm')->unsigned()->nullable();
            $table->rememberToken();
            $table->timestamps();
        });
    }

Solution

  • Instead of checking null you can use whereHas.Try changing.

    $orders = Order::with('user')->whereHas('user')->latest()->paginate(20);
    

    Your relationship is wrong so

    Order.php:

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

    User.php:

    public function order()
    {
       return $this->hasOne(Order::class);
    }