I have M-to-M morphToMany relationship:
User::class has morphToMany Building::class through buildable table (Many Buildings can have many Users and many Users can have many Buildings)
Building::class is used morphToMany with many classes
building_id | buildable_type | buildable_id
1 | App\Models\User| 1
1 | App\Models\Car | 1
Each Building hasMany Floor::class
How can I select $user->floors and have a list with every floor that applies to the user?
I know I can select $user->building->floors, what if I want to write a direct relationship?
class User extends Model {
public function floors()
{
return $this->hasManyThrough(
Floor::class,
"buildable"
);
}
}
I have three table country, state, customer_contacts. I want display all customer details into list view structure. But in my customer table only id save of country and state respectively. I want to fetch Country nad state Name from other two table .
Table structure as follows :
1. Country
id name
1 India
2 Canada
2. State
id name country_id
1 Mumbai 1
2 Delhi 1
3 abc 2
4 xyz 2
3. Customer_contact
id c_name country_id state_id
1 abcdee 1 2
2 xyzerr 1 1
3 extraa 2 3
4 newsss 2 4
i want to fetch customer name with country name and state name.
I am using below query to fetch data but getting only customer_contact data how to fetch name using any query or relationship.
$data = CustomerContact::with('Country', 'State')->get();
I am using relationship as follow:
1) Country Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Country extends Model
{
public function state()
{
return $this->hasMany(State::class);
}
public function customercontact()
{
return $this->hasMany(CustomerContact::class);
}
}
2) State Model
class State extends Model
{
public function customercontact()
{
return $this->hasMany(CustomerContact::class);
}
public function country()
{
return $this->belongsTo(Country::class);
}
}
3) CustomerContact
use Illuminate\Database\Eloquent\Model;
class CustomerContact extends Model
{
protected $guarded = [];
public function country()
{
return $this->belongsTo(Country::class);
}
public function state()
{
return $this->belongsTo(State::class);
}
}
I want show data in list view like CustomerName, CountryName,StateName.
When i do
dd($data)
getting data with country and state id but relationship getting null value.
Help me in this.
On CustomerSupport you defined two function country() and state(), so your code will be :
$data = CustomerContact::with('country','state')->get();
Or,
$data = CustomerContact::with('country')->with('state')->get();
I have 3 tabes categories, sub_categories & products
category table
---------------------
| id | category_name |
---------------------
sub_category table
--------------------------------------------
| id | category_id(FK) | sub_category_name |
--------------------------------------------
product table
-----------------------------------------------------------------
| id | sub_category_id(FK) | product_name | product_description |
-----------------------------------------------------------------
**How do I get product category name using hasOneThrough eloquent relationship ( or using any other relationship).
I tried this in product model **
public function category(){
return $this->hasOneThrough(
Category::class,
SubCategory::class
);
}
But it gives error: Unknown column 'sub_categories.product_id'
You can install this external package staudenmeir/belongs-to-through to add the relationship you need.
class Product extends Model
{
public function subCategory()
{
return $this->belongsTo(SubCategory::class);
}
public functoin category()
{
return $this->belongsToThrough(Category::class, SubCategory::class);
}
}
class SubCategory extends Model
{
public functoin category()
{
return $this->belongsTo(Category::class);
}
}
class Category extends Model
{
public function subCategories()
{
return $this->hasMany(SubCategory::class);
}
public functoin products()
{
return $this->hasManyThrough(Product::class, SubCategory::class);
}
}
If you need to access Category directly from Product, and want to use laravels functions like $product->category()->attach($category->id) etc, then you need this dependency to achieve that.
If you are ok with doing:
$product->subCategory->category;
// or
$product->subCategory->category()->attach($category->id);
Then you don't need the dependency and you can exclude the category relationship on the Product model.
I am in the process of porting a project to Laravel.
I have two database tables which are in a One-To-Many relationship with each other. They are joined by three conditions. How do I model this relationship in Eloquent?
I am not supposed to modify the database schema, since it has to remain backwards compatible with other things.
I have tried the following, but it doesn't work.
The owning side:
use Illuminate\Database\Eloquent\Model;
class Route extends Model
{
public function trips()
{
return $this->hasMany('Trip', 'route_name,source_file', 'route_name,source_file')
}
}
The inverse side:
use Illuminate\Database\Eloquent\Model;
class Trip extends Model
{
public function routes()
{
return $this->belongsTo('Route', 'route_name,source_file', 'route_name,source_file');
}
}
Example Route database values:
id | route_name | source_file
---------------------------------------
1 | Berlin - Paris | file1.xls
2 | Madrid - London| file2.xls
3 | Berlin - Paris | file3.xls
Example Trip database values:
id | route_name | source_file | duration
---------------------------------------------------------
1 | Berlin - Paris | file1.xls | 78
2 | Madrid - London | file2.xls | 241
3 | Berlin - Paris | file3.xls | 65
1 | Berlin - Paris | file1.xls | 95
1 | Berlin - Paris | file1.xls | 65
Route and Trip have other attributes, which I did not include here for brevity.
Is this possible in Eloquent?
I had to deal with a similar problem. The solution provided by #fab won't work with eager loading because $this->source_file would be null at the time the relationship is processed. I came up with this solution
After installing Compoships and configuring it in your models, you can define your relationships matching multiple columns.
The owning side:
use Illuminate\Database\Eloquent\Model;
use Awobaz\Compoships\Compoships;
class Route extends Model
{
use Compoships;
public function trips()
{
return $this->hasMany('Trip', ['id', 'route_name', 'source_file'], ['route_id', 'route_name', 'source_file']);
}
}
The inverse side:
use Illuminate\Database\Eloquent\Model;
use Awobaz\Compoships\Compoships;
class Trip extends Model
{
use Compoships;
public function route()
{
return $this->belongsTo('Route', ['route_id', 'route_name', 'source_file'], ['id', 'route_name', 'source_file']);
}
}
Compoships supports eager loading.
As Jonathon already mentioned, you could try to add an where-clause to your relationship:
use Illuminate\Database\Eloquent\Model;
class Route extends Model
{
public function trips()
{
return $this->hasMany('Trip', 'route_name')->where('source_file', $this->source_file);
}
}
The inverse side:
use Illuminate\Database\Eloquent\Model;
class Trip extends Model
{
public function routes()
{
return $this->belongsTo('Route', 'route_name')->where('source_file', $this->source_file);
}
}
How i would tackle this would be to do something like this
class A
{
public function b1()
{
return $this->hasMany('B', 'prop1', 'prop1')
}
public function b2()
{
return $this->hasMany('B', 'prop2', 'prop2')
}
public function b3()
{
return $this->hasMany('B', 'prop3', 'prop3')
}
public function getBsAttribute()
{
$data = collect([$this->b1, $this->b2, $this->b3]);
return $data->unique();
}
}
Collecting all the single relations and returning them as unique collection, and obviously doing the same for the inverse, this should give you some data to work with.
OP was modified so no longer relevant, left in if any one needs an answer similar
I have three tables, stores, store_categories and product_categories. Structure of each table is below
stores
id name
1 Mystore
store_categories
id store_id product_category_id
1 1 1
2 1 2
product_categories
id name
1 Grocery
2 Vegetable
In my Store model, I write the relation
public function store_categories(){
return $this->hasMany('App\StoreCategory');
}
So to get all data of a store, I write i StoresController
$res = Store::with('store_categories')->get(); dump($res);
But the dump shows store_id and product_category_id in relations. How can I display their names( ie store name, product category name etc ) ?
You need to add Many to Many relationship as follows:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Store extends Model
{
/**
* The roles that belong to the user.
*/
public function categories()
{
return $this->belongsToMany('App\ProductCategory','store_categories','store_id','product_category_id');
}
}
Then you can perform the following:
$res = Store::with('categories')->get(); dump($res);