I've got a situation where multiple tables have a belongsTo relationship to a category table in laravel 5.4.
So I thought about this structure:
User table:
id
name
email
category_id <--
Category table
id
model_type
name
Is this possible with a morph relationship?
This would not be since model_type is just a constraint of which categories are available for which models. If you set it up like that you would add that constraint on each model's relation like:
class User extends Model
{
// User class
public function category()
{
return $this->belongsTo(Category::class)->where('model_type', '=', static::class);
}
}
Or since you have many models that belong to Category you could take that one step further and use a trait for the relation and place the trait on each model that belongs to Category:
trait BelongsToCategory()
{
public function category()
{
return $this->belongsTo(Category::class)->where('model_type', '=', static::class);
}
}
class User extends Model
{
use BelongsToCategory;
// User class
}
Related
I have three table:
categories table fields id, category_name
subcategories table fields id, category_id, subcategory_name
child_categories table fields id, category_id, subcategory_id, child_category_name
I have three model Category, Subcategory,
1) =>category model code
class Category extends model {
public function subcategory(){
return $this->hasMany(Subcategory::class);
}
public function Child_category(){
return $this->hasMany(Child_category::class);
}
}
2) =>Subcategory model code
class Subcategory extends model {
public function Category(){
return $this->belongsTo(Category::class);
}
}
3) =>Child_category model code
class Child_category extends model {
public function Category(){
return $this->belongsTo(Category::class);
}
}
how to make Eloquent relationship to find all data from child_categories table with related category & subcategory name?
Once the relationships are defined you can get them by simply calling the property that has the same name as the relation you need.
$category = Category::first();
$subcategory = $category->subcategory;
If you wanted to get all the categories with all subcategories and child categories in one line you can use the with() method to eagerload them efficiently.
$categories = Category::with(['subcategory', 'Child_category'])->get();
This will fetch all the categories, then fetch all the related subcategories and child categories and associate them appropriately.
I have 3 tables.
shops
shop_foods
foods
I need to fetch foods table data when I create hasmany relation with shops_food and store.
$this->hasMany('App\Diet\ShopFood', 'shop_id', 'id');
Please, show your code so we can know what are you trying to do.
But what I can see here is that you have a wrong relationship.
Why are you assigning hasMany in a Many to Many relationship?
In your Shop Model you can make a foods relationship with:
$this->belongsToMany('App\Diet\Food);
Then you can retreive you food when calling
$shop->foods
And the shop_foods with the Pivot property
If i understand correctly you want to get foods when you call shops->shop_foods. if is that
//first you call your shops as you want.
Shop::with(['shops_food' => function($query){
//the 'shops_food' relationship should be called within an array
//this way you could query the relationship as the eloquent model.
//that way you could call the 'foods' relationship inside the shops_food relationship.
$query->with('foods')
}])
...
Note that you must have the relationship declared in shop and shop_foods models
lets your models are like these
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Shop extends Model
{
//
public function shops_food()
{
//shop_id is the foreing key inside your shop_foods table
return $this->hasMany('App\ShopFood','shop_id');
}
....
}
then ShopFood Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class ShopFood extends Model
{
//
public function foods()
{
//shop_food_id is the foreing key inside your foods table
return $this->hasMany('App\Food','shop_food_id');
}
....
}
This reads as if you want
public function foods() {
$this->hasMany('App\Diet\Food');
}
in your ShopFood model and in your Shop model
public function shopfoods() {
$this->hasMany('App\Diet\ShopFood')->with('foods');
}
You can also make 2 separate relations in the Shop model:
public function shopfoods() {
$this->hasMany('App\Diet\ShopFood');
}
public function shopfoodsWithFoods() {
$this->hasMany('App\Diet\ShopFood')->with('foods');
}
So that way you can use whatever you need at that moment.
But the whole thing is really not clear...
I am not even sure how the 3 table are connected, so the hasMany are just guesses.
Nevertheless you can just go with the "with" function.
PS
There is also the possibility to just declare
protected $with = ['foods'];
in your ShopFood model, if you ALWAYS want those 2 connected. It's all in the documentation.
I have a table called invoiceDetails that has item_id as foreign key from another table called items which has category_id as foreign key from table called categories.
I want to do that following using eloquent:
$result = InvoiceDetail::groupBy('item_id')
->selectRaw('sum(qty) as qty, item_id')->with('item', 'category')->get();
but I am getting error:
Call to undefined relationship [category] on model [App\InvoiceDetail].
Here's my relation inside Category model:
public function invoiceDetail() {
return $this->hasManyThrough('App\InvoiceDetail', 'App\Item', 'category_id', 'item_id');
}
Any suggestions?
Not sure you would even need a hasManyThrough relation here, unless you want to fetch all InvoiceDatail objects belonging to all items which in turn belong to the Category. That part is not clear from your question.
But in your example you are fetching items with their category from distinct item_id.
The reason this is not working is because you are trying to fetch the category relation from the InvoiceDetail object, which does not exist.
->with('item', 'category')
You want to load the Category based on the item relation, not based on the InvoiceDetail, try the dot notation (given that you did define the other relations)
->with('item.category')
Relations should be like this:
class InvoiceDetail extends Model
{
public function item()
{
return $this->belongsTo(\App\Item::class);
}
}
class Item extends Model
{
public function invoiceDetails()
{
return $this->hasMany(\App\InvoiceDetail::class);
}
public function category()
{
return $this->belongsTo(\App\Category::class);
}
}
class Category extends Model
{
public function items()
{
return $this->hasMany(\App\Item::class);
}
public function invoiceDetails()
{
return $this->hasManyThrough(\App\InvoiceDetail::class, \App\Item::class, 'category_id', 'item_id');
}
}
You would want to use the hasManyThrough if, for example, you have a Category and you want to load all the InvoiceDetails directly.
dd($category->invoiceDetails);
Heyy, I have a Laravel project here, can u guys help me with this question about relationship?
I have the following database structure:
users
id
name
email
password
event
id
description
city_id
block_range
id
event_id
user_block_ranges
user_id
block_range_id
Explanation
users: A normal user authentication table. (has a belongsToMany relationship with user_block_ranges)
event: Stores event info. (has a hasMany relationship with block_range)
block_range: Save blocks of time of event. (has a belongsTo relationship with event)
The real question is: how do I get all the events of the user? Through the user_block_ranges then block_range relationship? Maybe using hasManyThrough?
Thanks in advance.
I believe your models look like this:
User model
class User extends Model
{
public function blockRanges()
{
return $this->belongsToMany('App\BlockRange', 'user_block_ranges', 'user_id', 'block_range_id');
}
}
Block Range model
class BlockRange extends Model
{
public function event()
{
return $this->belongsTo('App\Event');
}
}
To get all events of the user you can do this:
$user = App\User::find(1);
$events = array();
foreach ($user->blockRanges as $block_range) {
$events = $block_range->event;
}
User TABLE:
id -> int
email -> varchar
Tag TABLE:
id -> int
name -> varchar
tags_user TABLE
tab_id ->foreign('tag_id')->references('id')->on('tag');
user_id ->foreign('user_id')->references('id')->on('user');
how to get all tags from specific user?
thanks
You need many to many relationship:
In your user model:
class User extends Eloquent {
public function tags()
{
return $this->belongsToMany('Tag');
}
}
In your Tag model:
class Tag extends Eloquent {
public function users()
{
return $this->belongsToMany('User');
}
}
Then from your controller:
Utilize the many to many relationship.
$tags = User::find(1)->tags;
Important:
Three database tables are needed for this relationship: users, tags, and tag_user. The tag_user table is derived from the alphabetical order of the related model names, and should have user_id and tag_id columns.
Reference:
http://laravel.com/docs/eloquent#many-to-many