Reputation: 402
I am trying to make table relationships with laravel(5.6) eloquent. And I'm not able to retrieve relational table results from model. Below I mentioned the relation.
relationship : Item has one category
This is my item model
class InventoryItems extends Model
{
/**
* table row delete
*/
use SoftDeletes;
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'inventory_items';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $guarded = ['id'];
protected $fillable = ['name','type_id','category_id','sub_category_id','description','cost_price','sale_price','image_path','image','store_id','status'];
public function category()
{
return $this->belongsTo('App\ItemCategories', 'id', 'category_id');
}
}
This is my category model
class ItemCategories extends Model
{
/**
* table row delete
*/
use SoftDeletes;
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'item_categories';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $guarded = ['id'];
protected $fillable = ['name'];
}
This is my controller
public function index(Request $request)
{
$items = InventoryItems::all();
dd($items);
}
This is result
Collection {#722 ▼
#items: array:2 [▼
0 => InventoryItems {#719 ▼
#table: "inventory_items"
#guarded: array:1 [▶]
#fillable: array:11 [▼
0 => "name"
1 => "type_id"
2 => "category_id"
3 => "sub_category_id"
4 => "description"
5 => "cost_price"
6 => "sale_price"
7 => "image_path"
8 => "image"
9 => "store_id"
10 => "status"
]
#connection: "mysql"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:15 [▼
"id" => 1
"name" => "Dell Keyboard"
"type_id" => 1
"category_id" => 1
"sub_category_id" => 1
"description" => "<p>test key</p>"
"cost_price" => 100.0
"sale_price" => 500.0
"image_path" => null
"image" => null
"store_id" => 1
"status" => 1
"created_at" => "2018-06-02 14:31:32"
"updated_at" => "2018-06-02 14:31:32"
"deleted_at" => null
]
#original: array:15 [▶]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#forceDeleting: false
}
I'm new to eloquent relations and I referred laravel documentation and some other tutorials but it did not workout. Must be a silly mistake thought.
Upvotes: 1
Views: 1997
Reputation: 1908
First, try to add to your controller with('category')
, so the eloquent knows that you're calling the relationship. so your controller should look like
public function index(Request $request)
{
$items = InventoryItems::with('category')->get();
dd($items);
}
Second, i think the order of relationship foreing keys are wrong it should be
return $this->belongsTo('YourModel','foreing_key','other_model_key')
so your relationship should look like this
return $this->belongsTo('App\ItemCategories', 'category_id', 'id');
Upvotes: 2
Reputation:
There are a few things going on.
Firstly Laravel uses 'Eager Loading' when dealing with model relationships.
From the documentation. (https://laravel.com/docs/5.6/eloquent-relationships#eager-loading)
This means the relationship data is not actually loaded until you first access the property. However, Eloquent can "eager load" relationships at the time you query the parent model.
What this means is Laravel won't load your relationship until you try to access it.
For example the following code would lazy load the category.
foreach (InventoryItems::all() as $inventoryItem) {
dump($inventoryItem->category); // Laravel loads the category here and not before
}
You can also eager load the relationships when you retrieve the model itself.
$items = InventoryItems::all()->load('category'); // Laravel loads the category here.
dd($items);
The only thing to note here is that when eager loading, you should use the name of relationship function not the name of the model your retrieving.
if your category relationship was defined as
public function itemCategory()
You would use
InventoryItems::all()->load('itemCategory');
One thing to mention is that the ->load() only works on collections and not builders.
for Builders you would need to use ->with()
e.g.
InventoryItems::all()->load('category'); // all() has already returned a collection so we have to 'load' additional data
InventoryItems::where('condition','=','something')->with('category')->get(); // This is a builder (until we call get() or first()) so we can ask for the data to be delivered 'with' the category to the collection
Upvotes: 1