Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

DougT's avatar
Level 2

Struggling With Livewire Database Queries

Hey all,

it's been ages since I worked with DBs and I'm trying to pick up Livewire and I'm lost.

I'm tying to build a todo type app, but one that has multiple notepads (ie say one for housework, a shopping list, etc) with all their note items iterated below. I'm not sure where I've gone wrong, but I can't seem to access my note items without jumping through what seems like extra hoops

create_notepads_table.php

create_notes_table.php

Notepad.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;


class Notepad extends Model
{
    /** @use HasFactory<\Database\Factories\NotepadFactory> */
    use HasFactory;

    protected $fillable = [
        'table_name', 'table_desc'
    ];

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

    public function note(): HasMany{
        return $this->hasMany(Note::class);
    }
}

Note.php

<?php

namespace App\Models;

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

class Note extends Model
{
    /** @use HasFactory<\Database\Factories\NoteFactory> */
    use HasFactory;

    protected  $fillable = [
        'note_item',
        'note_desc'
    ];

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

User.php

<?php

namespace App\Models;

// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Str;
use Illuminate\Database\Eloquent\Relations\HasMany;

class User extends Authenticatable
{
    /** @use HasFactory<\Database\Factories\UserFactory> */
    use HasFactory, Notifiable;

....

    public function notepads(): HasMany{
        return $this->hasMany(Notepad::class);
    }

    public function notes(): HasMany{
        return $this->hasMany(Note::class);
    }
}

Livewire - Notepads.php (I know, poorly named)

<?php

namespace App\Livewire;

use Livewire\Component;
use App\Models\Notepad;
use App\Models\Note;
use Illuminate\Support\Facades\Auth;

class Notepads extends Component
{

    public function render()
    {
        return view('livewire.notepads',[
            'notepad' => Notepad::all(),
            'notes' => Note::all()
        ]);
    }
}

notepads.blade.php

<div class="grid auto-rows-min gap-4 md:grid-cols-3">
    @foreach($notepad as $item)
        <div class="relative aspect-video overflow-hidden rounded-xl border border-neutral-200 dark:border-neutral-700" wire:key{{ $item->id }}>
            <div class="w-full bg-gray-800 py-2">
                <h1 class="m-1 px-4 font-extralight">
                    {{ $item->table_name }}
                </h1>
            </div>
            <div class="font-extralight text-sm">
                @foreach($notes as $note_item)
                    <p class="mt-2 px-4">
                        {{ $note_item }}
                    </p>
                @endforeach
            </div>
        </div>
    @endforeach
</div>

This outputs ALL the notes for ALL the notepads, but I want just the notes that belong to a specific notepad. I'm lost as to where to go next - or if my database relationships are buggered. I think I can do a where query in the blade file but that seems hacky. Do I use a nested Livewire component?

0 likes
4 replies
LaryAI's avatar
LaryAI
AI
Best Answer
Level 58

To display only the notes that belong to a specific notepad, you need to adjust your query logic and the way you pass data to your Blade view. Instead of fetching all notes separately, you should leverage the Eloquent relationships you've defined to fetch notes related to each notepad.

Here's how you can modify your Livewire component and Blade view to achieve this:

Livewire Component

In your Notepads Livewire component, you should fetch the notepads with their related notes using Eloquent's with method. This will eager load the notes for each notepad, reducing the number of queries and making it easier to access related data.

namespace App\Livewire;

use Livewire\Component;
use App\Models\Notepad;
use Illuminate\Support\Facades\Auth;

class Notepads extends Component
{
    public function render()
    {
        return view('livewire.notepads', [
            'notepads' => Notepad::with('note')->get()
        ]);
    }
}

Blade View

In your Blade view, you can now iterate over each notepad and its related notes directly. This ensures that only the notes belonging to each specific notepad are displayed.

<div class="grid auto-rows-min gap-4 md:grid-cols-3">
    @foreach($notepads as $notepad)
        <div class="relative aspect-video overflow-hidden rounded-xl border border-neutral-200 dark:border-neutral-700" wire:key="{{ $notepad->id }}">
            <div class="w-full bg-gray-800 py-2">
                <h1 class="m-1 px-4 font-extralight">
                    {{ $notepad->table_name }}
                </h1>
            </div>
            <div class="font-extralight text-sm">
                @foreach($notepad->note as $note)
                    <p class="mt-2 px-4">
                        {{ $note->note_item }}
                    </p>
                @endforeach
            </div>
        </div>
    @endforeach
</div>

Explanation

  • Eager Loading: By using Notepad::with('note')->get(), you are eager loading the notes for each notepad. This means that when you retrieve the notepads, their associated notes are also retrieved in a single query, which is more efficient.

  • Blade Iteration: In the Blade view, you iterate over $notepads and for each notepad, you access its related notes using $notepad->note. This ensures that only the notes associated with the current notepad are displayed.

This approach is clean and leverages Laravel's Eloquent ORM to handle relationships efficiently.

1 like
DougT's avatar
Level 2

@jlrdw Hey! I'm working through Jeremy's course (I just started form handling) but I'm trying to apply stuff on a second project at the same time.

Snapey's avatar

in your render method



return view('livewire.notepads',[
            'notepads'=> auth()->user()->notepads()->with('notes')->get()
];

you can then iterate over $notepads in the view with each notepad having a collection of notes

<div class="grid auto-rows-min gap-4 md:grid-cols-3">
    @foreach($notepads as $notepad)
        <div class="relative aspect-video overflow-hidden rounded-xl border border-neutral-200 dark:border-neutral-700" wire:key{{ $notepad->id }}>
            <div class="w-full bg-gray-800 py-2">
                <h1 class="m-1 px-4 font-extralight">
                    {{ $notepad->table_name }}
                </h1>
            </div>
            <div class="font-extralight text-sm">
                @foreach($notepad->notes as $note)
                    <p class="mt-2 px-4">
                        {{ $notepad->note_item }}
                    </p>
                @endforeach
            </div>
        </div>
    @endforeach
</div>

you also need to edit your notepad model and change note function to notes as this relationship is for a hasMany and should be named plurally

Please or to participate in this conversation.