1

If I have properties table, and 2 other tables:

 *property_characteristics
  - property_id (i.e. 1)
  - characteristic_id (i.e. 5 - join with default_characteristics)
  - value (i.e. 3 - aka 3 rooms)
 *default_characteristics
  - id (i.e. 5)
  - name (i.e. rooms)

In the Property.php model I have:

public function characteristics()
{
return $this->belongsToMany('Proactiv\DefaultCharacteristic', 'property_characteristics', 'property_id', 'characteristic_id');
}

How can I get the number of rooms (value from property_characteristics) for a property starting from:

$property = Properties::find(1);

I would need something like this in view:

$property->characteristics->rooms // should return 3 which is the value columns on property_characteristics table

2 Answers2

2

Since the value is on your pivot table, you need to tell Laravel about this extra field. Add to your belongsToMany line to make:

return $this->belongsToMany('Proactiv\DefaultCharacteristic', 'property_characteristics', 'property_id', 'characteristic_id')
    ->withPivot('value');

Then select characteristics with the name you want, rooms, and get the value:

echo $property->characteristics()->with('name', 'rooms')->first()->pivot->value;

Alternatively, add a getter to your Property model which does this for you (you'll still need to add that withPivot part to the relationship):

public function getRoomsAttribute()
{
    return $this->characteristics()
        ->where('name', 'rooms')
        ->first()
        ->pivot
        ->value;
}

Then you can get the number of rooms in a similar way to how you originally wanted to, with $property->rooms.

Or you could generalize this to get any characteristic:

public function getCharacteristic($name)
{
    return $this->characteristics()
        ->where('name', $name)
        ->first()
        ->pivot
        ->value;
}

And then get the number of rooms with $property->getCharacteristic('rooms').

tremby
  • 9,541
  • 4
  • 55
  • 74
  • I used `getCharacteristic` because I have dynamic filters. Thank you. – Sebastian Corneliu Vîrlan Mar 14 '16 at 20:38
  • One other thing to point out is that I used `first()` in my answer. I don't know if you ever have two characteristic entries for the same property with the same name, but if so you'll be only retrieving one of them. – tremby Mar 14 '16 at 21:06
  • Another thing is if you don't *always* want to retrieve the `value` pivot data, you could move the `withPivot` call to inside the `getCharacteristic` method. Then it'd only be applied to queries generated by this method. – tremby Mar 14 '16 at 21:07
  • Thank you. A problem that I encountered was when for a property I have rooms and for other I don't. For the one I don't have rooms I get `Trying to get property of non-object` because of course does not exist. How can I handle this? For example to return a string 'no' or nothing. – Sebastian Corneliu Vîrlan Mar 14 '16 at 21:34
0

First, you have to tell your relationship to make your additional field available. You do this using the withPivot() method:

public function characteristics() {
    return $this->belongsToMany('Proactiv\DefaultCharacteristic', 'property_characteristics', 'property_id', 'characteristic_id')
        ->withPivot('value');
}

Now you can access your value on the pivot table. You do this like so:

$property = Properties::find(1);

foreach ($property->characteristics as $characteristic) {
    echo $characteristic->pivot->value;
}

You can read more about this in the documentation here, under the Retrieving Intermediate Table Columns heading.

patricus
  • 59,488
  • 15
  • 143
  • 145