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

jake2025's avatar

Laravel: Issue in getting the value of one to many relationship

Greetings laracast :D.

I was having a problem between locations (table) and devices (table)

this is my location model:


class Location extends Eloquent { protected $fillable = array( 'id', 'name' ); public function devices() { return $this->hasMany('Device'); } }

and this is my device model:

class Device extends Eloquent {
 public function locations() {
     return $this->belongsTo('Location');
   }
}

and when i do :

@foreach($locations as $locations)
     @foreach($locations->devices as $location_device)
          {{ $location_device->name . "" . $locations->name}} 
     @endforeach
@endforeach`

it only shows devices who has location_id but what i want to do is get all devices with or without location_id.

0 likes
22 replies
mikebronner's avatar

Yes, that is because you are pulling Devices based on Locations. This means you will ONLY get Devices that are attached to Locations. To get all Devices, you have to add the following in your controller:

$devices = Device::all();
return View::make('devices', compact(['locations', 'devices']);

Then in your code, loop through the devices, instead of locations:

@foreach ($devices as $device)
// ...
@endforeach

Your loop above would be better written as:

@foreach($locations as $location)
    @foreach($location->devices as $device)
        {{ $device->name . "" . $location->name }}
    @endforeach
@endforeach

I might not be understanding your intent correctly, as I don't see why you would want to loop through devices, regardless if they are associated with location or not, in a location loop. Could you explain your use-case in more detail? That may help us help you better. :)

jake2025's avatar

This is the flow of my system:

Devices Table: Id item_id location_id name

Locations Table: Id, name

User will add an item named mouse (a href). User will also add a location for example: 000-0001

Now user will click the item Mouse and inside of that page he can add a device mouse. For example Logitech Mouse after he add the device it will be displayed on the HTML table

It will display the Device name, the availability (If Available or Assigned to), status (Defective or Normal), and actions (Assign, Edit, Delete Device).

Now after he add the device Logitech even though the device Logitech has no location id it should be displayed on the html table so that he can assign it to a location.

jake2025's avatar

What i want to do is show the devices even though they don't have location_id. Because you can't assign a device if you can't see it on the HTML table.

jake2025's avatar

I did some code and works but i dont know if this is valid in concept of the MVC

here's the code:

i put that code in the views so i thought i must ask the pros to confirm if this is valid code or not.

$locat_name = Location::find($devList->location_id);
             $locsName = $locat_name->name;
lprice's avatar

Views should have no business logic or data access logic in them. It is also a bad practice to access data objects (e.g. Locations model) directly from a view layer, otherwise you are badly breaking the MVC pattern already and your maintainability, testability and extensibility of your software reduces drastically and not only is the controllers leaky, but it is just jumping over them completely.

Your controller can do something like this, then that initial code of yours will work also, because the devices will be embedded into each location:

$locations_with_devices = Location::with('Device')->get();
return View::make('locations', $locations_with_devices);

to see what the datastructure looks like just do this and look at the JSON response and then apply in your view your loops accordingly to the returned structure:

$locations_with_devices = Location::with('Device')->get();
return $locations_with_devices;
jake2025's avatar

What should be putted on the with? Model or the database devices?

lprice's avatar

Note I've removed the compact method, so that you can work with object notation in your view code. This is what compact does: http://us2.php.net/manual/en/function.compact.php

$locations_with_devices = Location::with('Device')->get();
return View::make('locations', $locations_with_devices);
jake2025's avatar

But how can i compare the location_id on the device to the location table on my loop?

i did this but i got an error:

$locs->devices->name

Trying to get property of non-object

lprice's avatar

Eloquent creates an embedded resource, so you don't need to compare it, it has done it already for you with the "with('Device')" statement.

What does this return? (just one example please, not the whole response) or use http://laravel.io/bin

$locations_with_devices = Location::with('Device')->get();
return $locations_with_devices;
jake2025's avatar

It returns the data types of the data table like this one

 protected 'connection' => null
          protected 'table' => null
          protected 'primaryKey' => string 'id' (length=2)
jake2025's avatar

and if i try this:

dd($locs->devices->id);

it returns:

Undefined property: Illuminate\Database\Eloquent\Collection::$devices
lprice's avatar
lprice
Best Answer
Level 21

Ok, please read the section on Eloquent, and start with the following smaller steps in you controller:

1) return Location::all(); //you should get a collection of Locations in JSON

2) return Device::all(); //you should get a collection of Devices in JSON

Because the relationships are defined in your Models you then should be able to do

3) return Location::with('Device')->get(); //you should get a collection of Locations with embedded Devices in JSON

or even the reverse

4) return Device::with('Location')->get(); //you should get a collection of Devices with embedded Locations in JSON

If that doesn't work you have other problems you need to first solve and debugging that on the forum is bit too much ;)

Ping back if you got it going.

jake2025's avatar

Oh my God it's working now! I mean i can finaly use this :

$locss->location->Name
jake2025's avatar

I solved my problem by changing this:

 public function locations() {
     return $this->belongsTo('Location');
   }

to this:

 public function location() {
     return $this->belongsTo('Location');
   }
lprice's avatar

Ah... maybe Laravel is so clever to see that you use belongsTo which would mean your referring to a single parent object, hence it sees you are using plural in the name. It does this through reflection, in a couple of other places this is also used. Does the "with('Device')" now work?

jake2025's avatar

Yes :D. Thank you sir :D. Can you tell me sir what should be the naming convention in functions on models?

greg_sudderth's avatar

This page (and the 4 tests specifically) really, really, really helped me. Thanks guys! This kind of situation is a 1M$ example of why Tinker is so helpful!

Please or to participate in this conversation.