Msoft's avatar
Level 1

How to display the last record from a manyToMany relationship in Laravel 5.6

I have multiple images in my uploads table with related to vehicle_id, as foreign key like this,

uploads table
id          fileName        vehicle_id
1             1.jpg                      1
2            2.jpg                       1
3            3.jpg                       1
4            4.jpg                       1
5            28.png                 2
6            28.png                  2
7            29.png                  2
8            30.png                  3
9            31.png                      3
10           56.png                  3

The vehicle table have many to many relationship with the image table and data grap using eager loader in VehicleController,

$vehicles = Vehicle::with('uploads')->get();
        return view('vechicles.index')->withVehicles($vehicles);

Now these images are showing in the vehicles/index.blade.php file

@foreach($vehicle->uploads as $upload)

         <tr>
                        <td><a href="{{route('vechicles.show',$vehicle->id)}}"><img src="/images/{{ $upload->resized_name }}"></a></td>

                    </tr>

        @endforeach

My problem is occurred now, in this way, I can show all images in the table whith related to proper vehicle_id but, I need only show one image (to matching vehicle_id) like thumbnail to above line. Then how can I configure this? actually I need only one image to print in index.blade.php to related in each vehicle_id, as an example here are 4 images with related to vehicle_id 1. but I need only print decending oder one image to print and same to vehicle_id 2 and etc.... how can do this?

0 likes
25 replies
Msoft's avatar
Level 1

My Upload Model is

class Upload extends Model
{
    public function vehicle()
    {
        return $this->belongsTo(Vehicle::class);
    }
}
Cronix's avatar

I answered your other similar thread, but this is slightly different.

as an example here are 4 images with related to vehicle_id 1. but I need only print decending oder one image to print and same to vehicle_id 2 and etc.... how can do this?

Looking at your db structure in the first example, there are several ways.

Does your uploads table use timestamps (updated_at/created_at)?

If so, I'd create a 2nd relationship, just to get the single thumbnail image. Since you only want to display one, it doesn't make sense to retrieve them all.

Something like

public function thumbnail() {
    return $this->hasMany(Upload::class)->latest()->first();
}

That will get the images, sort by descending order (via created_at), and return the first one.

So in the cases where you only want to display the thumbnail image, you'd just

$vehicles = Vehicle::with('thumbnail')->get();
@foreach ($vehicles as $vehicle)
    // display vehicle info
    {{ $vechicle->make}} {{ $vehicle->model }}

    // display thumbnail for this vehicle
    <img src="/uploads/{{ $vehicle->thumbnail->url }}">
@endforeach 

That's one way.

And then on pages where you want to display all images for the vehicle, just use the other images relationship previously defined, and loop over them.

Msoft's avatar
Level 1

@Cronix this is My current blade file,

@if($vehicles)

@foreach($vehicles as $vehicle)
{{$vehicle->district}}
{{$vehicle->town}}
{{$vehicle->brand}}
{{$vehicle->model}}


 <td><a href="{{route('vechicles.show',$vehicle->id)}}"><img src="/images/{{ $vehicle->thumbnail->->resized_name }}"></a></td>
@endforeach
@endif

but I got following errors,

Call to undefined method Illuminate\Database\Query\Builder::addEagerConstraints()


Msoft's avatar
Level 1

@Cronix now this error

Call to undefined method Illuminate\Database\Query\Builder::addEagerConstraints()
Cronix's avatar

Ah, sorry, try this

public function thumbnail() {
    return $this->hasMany(Upload::class)->latest()->limit(1);
}

first() executes the query, which shouldn't be in a relationship.

Msoft's avatar
Level 1

@Cronix now got this,

syntax error, unexpected '->' (T_OBJECT_OPERATOR), expecting identifier (T_STRING) or variable (T_VARIABLE) or '{' or '$'
in 2bbc0c9aa7ed16ed8b729cad9d5c903d41b123c5.php line 30

that means this line

<td><a href="{{route('vechicles.show',$vehicle->id)}}"><img src="/images/{{ $vehicle->thumbnail->->resized_name }}"></a></td>
Cronix's avatar

Again, you have a double -> operator (->->). Remove one.

$vehicle->thumbnail->resized_name
Msoft's avatar
Level 1

@Cronix now got this,

Property [resized_name] does not exist on this collection instance. (View: C:\Users\msoft\Desktop\acxian\resources\views\vechicles\index.blade.php)
Cronix's avatar

Don't know how to help you with that one. I got "resized_name" from your first post. Maybe it should be "fileName"? That's what you showed in your uploads table (id, fileName, vehicle_id)

Cronix's avatar

Show the output of this from your controller.

$vehicles = Vehicle::with('thumbnail')->first();
dd($vehicles);

expand the attributes, and relationships. I'd like to see the actual data being worked on.

Msoft's avatar
Level 1

@Cronix it is print this,

Collection {#232 ▼
  #items: array:4 [▼
    0 => Vehicle {#236 ▶}
    1 => Vehicle {#237 ▶}
    2 => Vehicle {#238 ▶}
    3 => Vehicle {#239 ▶}
  ]
}
Cronix's avatar

You didn't expand the attributes and relationships that I asked. Click the triangle next to the first vehicle. It will expand and show the properties. Then click the triangle next to "relationships", then click on the triangle next to the thumbnail relationship to expand it. Need to see the actual data inside of each model returned.

Use this query to get the first() one instead of all()

$vehicles = Vehicle::with('thumbnail')->first();
dd($vehicles);
Msoft's avatar
Level 1

@Cronix ok this now,

Vehicle {#233 ▼
  #connection: "mysql"
  #table: null
  #primaryKey: "id"
  #keyType: "int"
  +incrementing: true
  #with: []
  #withCount: []
  #perPage: 15
  +exists: true
  +wasRecentlyCreated: false
  #attributes: array:16 [▼
    "id" => 52
    "district" => "Sydney"
    "town" => "Nugegoda"
    "brand" => "Toyota"
    "model" => "121"
    "year" => "2000"
    "condition" => "on"
    "detail" => "this is first"
    "price" => "1234"
    "telephone" => "1236547895"
    "email" => "[email protected]"
    "name" => "Nalaka"
    "created_at" => "2018-07-11 15:37:10"
    "updated_at" => "2018-07-11 15:37:10"
    "user_id" => 4
    "catagory_id" => 1
  ]
  #original: array:16 [▼
    "id" => 52
    "district" => "Sydney"
    "town" => "Nugegoda"
    "brand" => "Toyota"
    "model" => "121"
    "year" => "2000"
    "condition" => "on"
    "detail" => "this is first"
    "price" => "1234"
    "telephone" => "1236547895"
    "email" => "[email protected]"
    "name" => "Nalaka"
    "created_at" => "2018-07-11 15:37:10"
    "updated_at" => "2018-07-11 15:37:10"
    "user_id" => 4
    "catagory_id" => 1
  ]
  #casts: []
  #dates: []
  #dateFormat: null
  #appends: []
  #events: []
  #observables: []
  #relations: array:1 [▼
    "thumbnail" => Upload {#238 ▼
      #connection: "mysql"
      #table: null
      #primaryKey: "id"
      #keyType: "int"
      +incrementing: true
      #with: []
      #withCount: []
      #perPage: 15
      +exists: true
      +wasRecentlyCreated: false
      #attributes: array:7 [▼
        "id" => 15
        "filename" => "f1d95d44e91b9c442bc81bd25c4e4ee1b37616fb.jpg"
        "resized_name" => "f1d95d44e91b9c442bc81bd25c4e4ee1b37616fb42.jpg"
        "original_name" => "indexs.jpg"
        "created_at" => "2018-07-11 15:41:11"
        "updated_at" => "2018-07-11 15:41:11"
        "vehicle_id" => 52
      ]
      #original: array:7 [▼
        "id" => 15
        "filename" => "f1d95d44e91b9c442bc81bd25c4e4ee1b37616fb.jpg"
        "resized_name" => "f1d95d44e91b9c442bc81bd25c4e4ee1b37616fb42.jpg"
        "original_name" => "indexs.jpg"
        "created_at" => "2018-07-11 15:41:11"
        "updated_at" => "2018-07-11 15:41:11"
        "vehicle_id" => 52
      ]
      #casts: []
      #dates: []
      #dateFormat: null
      #appends: []
      #events: []
      #observables: []
      #relations: []
      #touches: []
      +timestamps: true
      #hidden: []
      #visible: []
      #fillable: []
      #guarded: array:1 [▼
        0 => "*"
      ]
    }
  ]
  #touches: []
  +timestamps: true
  #hidden: []
  #visible: []
  #fillable: []
  #guarded: array:1 [▼
    0 => "*"
  ]
}

Cronix's avatar

Good, that all looks correct! Now show your current updated view where you are looping over $vehicles.

It should be something like

@foreach ($vehicles as $vehicle)
    // display vehicle info
    {{ $vechicle->brand}} {{ $vehicle->model }}

    // display thumbnail for this vehicle
    <img src="/uploads/{{ $vehicle->thumbnail->resized_name }}">
@endforeach 
Msoft's avatar
Level 1

@Cronix it is like this,

@if($vehicles)

@foreach($vehicles as $vehicle)
{{$vehicle->district}}
{{$vehicle->town}}
{{$vehicle->brand}}
{{$vehicle->model}}


 <td><a href="{{route('vechicles.show',$vehicle->id)}}"><img src="/images/{{ $vehicle->thumbnail->->resized_name }}"></a></td>
@endforeach
@endif

but still error here

Cronix's avatar

Lol, for the third time, remove the double -> (->->)operator. That's not legal in php. Use one.

Cronix's avatar

And your controller method is this?

$vehicles = Vehicle::with('thumbnail')->get();

return view('vechicles.index')->withVehicles($vehicles);

Other than that, it should work. The data is being retrieved properly, you are getting a single image for the vehicle, and the data looks good from your dd() output...

Msoft's avatar
Level 1

@Cronix yes same controller here I think problem with this link,

<td><a href="{{route('vechicles.show',$vehicle->id)}}"><img src="/images/{{ $vehicle->thumbnail->resized_name }}"></a></td>
Cronix's avatar

Ok, I believe the problem is at least one of your vehicles doesn't have any images associated with it.

To confirm, do this in your view.

@foreach($vehicles as $vehicle)
{{$vehicle->district}}
{{$vehicle->town}}
{{$vehicle->brand}}
{{$vehicle->model}}


{{ dump($vehicle->thumbnail) }}
@endforeach 

Then for each vehicle, expand the dump in the view (the triangle again). One of them is probably empty, so resized_name obviously won't exist if there isn't a thumbnail record for it.

Msoft's avatar
Level 1

@Cronix ok it is generated following thing

[{"id":18,"filename":"a15376d290086a37be68ffc7e500c0724da350e7.jpg","resized_name":"a15376d290086a37be68ffc7e500c0724da350e7mE.jpg","original_name":"indexd.jpg","created_at":"2018-07-13 13:04:33","updated_at":"2018-07-13 13:04:33","vehicle_id":58}] 
Cronix's avatar

try

<td><a href="{{route('vechicles.show',$vehicle->id)}}"><img src="/images/{{ $vehicle->thumbnail->first()->resized_name }}"></a></td>

Please or to participate in this conversation.