5

I have three models all related by one-to-many. Category, Subcategory and Style. I have relationships working both ways - though I seem to have a problem accessing related attributes.

After my queries have ran, I'm left with this an instance of Style where 'relations' is an instance of Subcategory, and 'relations' in Subcategory is an instance of Category. Which is all correct.

The problem is that I now seem to not be able to access the related model instances. For example, if I call:

$style->subcategory->name;

I get 'Trying to get property of non-object'. So I tried calling just $style->subcategory and the result is '1'.

Why doesn't $style->subcategory return the instance of the subcategory model? Am I missing something or is my understanding incorrect?

--EDIT--

Models

Category

<?php

namespace Paragon\Products;

use Illuminate\Database\Eloquent\Model as Eloquent;

class Category extends Eloquent {

    protected $table = 'product_categories';

    protected $fillable = [
            'name',
            'slug',
            'image'
    ];

    public function subcategories() {
            return $this->hasMany('Paragon\Products\Subcategory', 'category');
    }

}

Subcategory

<?php

namespace Paragon\Products;

use Illuminate\Database\Eloquent\Model as Eloquent;

class Subcategory extends Eloquent {

    protected $table = 'product_subcategories';

    protected $fillable = [
            'category',
            'name',
            'slug',
            'image'
    ];

    public function styles() {
            return $this->hasMany('Paragon\Products\Style', 'subcategory');
    }

    public function category() {
            return $this->belongsTo('Paragon\Products\Category', 'category');
    }

}

Style

<?php

namespace Paragon\Products;

use Illuminate\Database\Eloquent\Model as Eloquent;

class Style extends Eloquent {

    protected $table = 'product_styles';

    protected $fillable = [
            'subcategory',
            'name',
            'slug',
            'image'
    ];

    public function subcategory() {
            return $this->belongsTo('Paragon\Products\Subcategory', 'subcategory');
    }

}

Query

$style->where($id, $item)->with('subcategory.category')->first();

Tables

Paragon\Products\Category

ID    ...
1
2

Paragon\Products\Subcategory

ID   Category    ...
1    2
2    2

Paragon\Products\Style

ID   Subcategory    ...
1    1
2    1

Since the subcategory method in the Style model should refer to a single instance of Subcategory and not a Collection of them, shouldn't I be able to just call attributes the way I am (or am trying to)?

Evan Carslake
  • 2,267
  • 15
  • 38
  • 56
Mike Kaperys
  • 160
  • 1
  • 1
  • 9

2 Answers2

17

Ok I think I see now what is going on. Your Eloquent model is called subcategory, but so is the foreign key. So when you call

$style->subcategory

That is returning the foreign key instead of the model. To fix this, I'd recommend changing the name of the foreign key id to subcategory_id. If you can't change the database, you could force it to use the model by chaining the method with something like this

$style->subcategory()->first()->name

Edit: Another idea, you could change the name of the relationship to something like

public function subcategory_item()
{
  return $this->belongsTo('Paragon\Products\Subcategory', 'subcategory');
}

Then you ought to be able to properly reference it with

$style->subcategory_item->name
Adrian Flannery
  • 351
  • 1
  • 4
0

I am taking a shot in the dark here. But I will try and explain how to work with collection and difference between first and get.

$users= $user-> with('images') -> first(); <-- this is first  row in the table users, each user has many images.
$users-> username; //works;

$users-> images-> image_name; // wont work , model has many ,    
you get error <-- Trying to get property of non-object. 
// access the proprety image and loop through the collection of objects.
$images = $user-> images; // 

foreach ($images as $image){
  echo $image- >image_name; 
}

on the other hand if the image did belong to one user and the user has one image. You can access image_name like this

$user -> image(() -> image_name;

in your case

$style -> subcategory() -> name;

to get a style by id with subcategoty

$style -> with('subcategry') -> where('id', $styleId) -> first();
mdamia
  • 4,447
  • 1
  • 24
  • 23
  • I'm trying to access a single model. Style has one Subcategory, but Subcategory has many Styles. Thankyou for your answer though – Mike Kaperys Aug 27 '15 at 17:48