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

muuucho's avatar
Level 11

Tweaking database's column value before sending to view

In table suppliers I have a column 'img_path'. I like to change each grabbed value from that column to 'thumbnails/'.$suppliers->img_path before I send $suppliers to the view, how can I do that? The render method:

{
    
  $suppliers = Supplier::query()
      ->select(['suppliers.*', 'users.name as userName'])
      ->join('users', 'users.id', '=', 'suppliers.ub');      
    
    $suppliers->orderBy($this->sortColumn, $this->sortDirection);
    return view('livewire.suppliers.all', [
        'suppliers' => $suppliers->paginate(10)
    ]);
}
0 likes
7 replies
tykus's avatar
tykus
Best Answer
Level 104

You can make an Accessor on the Supplier model:

    protected function imgPath(): Attribute
    {
        return Attribute::make(
            get: fn (string $value) => "thumbnails/$value",
        );
    }
1 like
martinbean's avatar

@muuucho Create an accessor, and create it with a different name so that you can still access the original attribute value if you need to for whatever reason. You might not need to today, but you might in the future.

public function imageUrl(): Attribute
{
    return Attribute::make(
        get: fn (mixed $value, array $attributes) => sprintf('thumbnails/%s', $attributes['img_path']),
    );
}
<img src="{{ $supplier->image_url }}">

Also, don’t abbreviate column and attribute names. There’s no real reason to abbreviate “image” to “img”.

However, you should ideally be using Laravel’s disks configuration, which would let you automatically generate URLs without needing to define accessors, i.e. Storage::url($supplier->image_path);

1 like
muuucho's avatar
Level 11

Actually i liked to change the file ending if it is .pdf to .jpg because I am using spatie/pdpf-to-image So I try:

return Attribute::make(
            #get: fn (string $value) => 'thumbnails/'.$value,
            get: fn (string $value) => end(explode('.', $value)) == 'pdf' ?? substr($value, 0, -3).'jpg',
        );

But I get the error Only variables should be passed by reference. What's wrong?

Snapey's avatar

@muuucho You can't just change the file extension!

Get the pdf, run it through the converter then save the output as a new file with the jpg extension.

1 like
muuucho's avatar
Level 11

@Snapey Good point, I will save the correct filnamne in the data base from the beginninig

LaryAI's avatar
Level 58

To tweak the img_path column value before sending it to the view, you can use Eloquent's get method to retrieve the collection of suppliers and then modify each supplier's img_path attribute. Here's how you can do it:

  1. Retrieve the suppliers.
  2. Modify the img_path attribute for each supplier.
  3. Send the modified collection to the view.

Here's the updated code:

{
    $suppliers = Supplier::query()
        ->select(['suppliers.*', 'users.name as userName'])
        ->join('users', 'users.id', '=', 'suppliers.ub')
        ->orderBy($this->sortColumn, $this->sortDirection)
        ->get();

    // Modify the img_path for each supplier
    $suppliers->each(function ($supplier) {
        $supplier->img_path = 'thumbnails/' . $supplier->img_path;
    });

    return view('livewire.suppliers.all', [
        'suppliers' => $suppliers->paginate(10)
    ]);
}

In this solution:

  • We use the get method to retrieve the collection of suppliers.
  • We use the each method to iterate over each supplier and modify the img_path attribute.
  • Finally, we pass the modified collection to the view.

Note: The paginate method should be called on the query builder, not on the collection. If you need pagination, you should modify the img_path after paginating:

{
    $suppliers = Supplier::query()
        ->select(['suppliers.*', 'users.name as userName'])
        ->join('users', 'users.id', '=', 'suppliers.ub')
        ->orderBy($this->sortColumn, $this->sortDirection)
        ->paginate(10);

    // Modify the img_path for each supplier
    $suppliers->getCollection()->transform(function ($supplier) {
        $supplier->img_path = 'thumbnails/' . $supplier->img_path;
        return $supplier;
    });

    return view('livewire.suppliers.all', [
        'suppliers' => $suppliers
    ]);
}

In this updated solution:

  • We use the paginate method to paginate the results.
  • We use the getCollection method to get the collection of suppliers from the paginator.
  • We use the transform method to modify the img_path attribute for each supplier in the collection.
  • Finally, we pass the paginator to the view.

Please or to participate in this conversation.