how to return collection of eloquent models with pivot column? For example, there are M:N relationship between users and vats. I want to retrieve all users data( with vats and with pivot column (costOfDelivery) , which is in pivot table user_vat).
In my code I have:
$vats = Vat::whereHas('users', function($query) use ($user) {
$query->where('user_id', $user->id);
})->with('country')
->get();
but this return data from vats and country, not from pivot table "user_vat", how to retrieve also costOfDelivery?
To retrieve the data from pivot table, you must use pivot attribute
Something like this
foreach($users->roles as $role){
echo $role->pivot->created_at;
}
To return json, you can use the toJson() method like
$vat->toJson();
<?php
/**
* The model class with the belongsToMany user class relation.
*/
class Vat extends Model
{
public function user()
{
return $this->belongsToMany(\App\User::class)
->withPivot(['cost_of_delivery', /**Specific columns for the pivot.*/]);
}
}
<?php
/*
* Your query (which I think is a little bit complicated that it should be.
*/
$vats = Vat::whereHas('users', function($query) use ($user) {
$query->where('user_id', $user->id);
})->with(['country', 'users'])
->get();
I would use sth. like:
<?php
$user->load(['vats.country']);
$vats = $user->getRelationValue('vats');
And
$vats->first()->pivot->cost_of_delivery
should give you the cost of delivery of the first vat.
Related
I have a relationship on Orders and Customers.
a row from customers table :
customer_id
customer_name
customer_state
customer_city
1
Amin
Yazd
Yazd
a row from orders table :
order_id
customer_id
product_id
factor_id
1
1
3
4
Now I want order rows where customer_state is yazd.
Order.php
public function customer()
{
return $this->belongsToMany(Customer::class, 'orders', 'order_id', 'customer_id');
}
OrdersController.php
$state = "Yazd";
$reportItem = Order::whereHas("customer", function ($query) use ($state) {
$query->where('customer_state', $state)->get();
});
It doesn't work. How I can handle this?
What I understand from the given input you're not using the proper relation here:
The belongsToMany relation is used for many-to-many relations using an allocation table. But you are actually using a one-to-many relation => one customer can have many orders.
In this case you should use a belongsTo relation on Order Model or/and a hasMany relation on Customer Model:
// Order.php
public function customer() {
return $this->belongsTo(Customer::class)
}
// Customer.php
public function orders() {
return $this->hasMany(Order::class)
}
You have put get() at the wrong place. Change this
$reportItem = Order::whereHas("customer", function ($query) use ($state) {
$query->where('customer_state', $state)->get();
});
To
$reportItem = Order::whereHas("customer", function ($query) use ($state) {
$query->where('customer_state', $state);
})->get();
Learn more about laravel relations
I have a collection of products for a particular order like this ->
$products = $order->products()->with('store.seller')->get();
What I want to get is a $sellersCollection where,
each $seller has $stores
each $store has $products
[$seller - stores - products]
How can it be done efficiently without making another db call.
using eloquent relationship you can access this.use appropriate relationship hasOne() or hasMany() in your model.Ex. Seller->hasOne(store) and store->belongsTo(seller) like that.
Doing with eloquent way you could get the desired results as
$sellers = Seller::with('stores.products')->get();
Above will return you all sellers with their related stores and each store with their related products
class Seller extends Model{
public function stores(){
return $this->hasMany('App\Store', 'seller_id')
}
}
class Store extends Model{
public function products(){
return $this->hasMany('App\Product', 'product_id')
}
}
I believe order and products are related as m:m via pivot table so you could define their relation as belongsToMany
class Product extends Model{
public function orders(){
return $this->belongsToMany('App\Order')
}
}
Edit I want the particular $sellers who are associated with the order just made and with all the info of the products buyer ordered like quantity
$sellers = Seller::with(['stores.products.orders' => function ($query) use ($orderId) {
$query->where('id', '=', $orderId);
}])
->whereHas('stores.products.orders', function ($query) use ($orderId) {
$query->where('id', '=', $orderId);
})
->get();
I have this model for notifications table:
class Notification extends Model
{
public function users()
{
return $this->belongsToMany(User::class, 'notification_user', 'notification_id', 'user_id');
}
}
And this method in controller for getting data from notifications where id of notifications is related to a pivot table named notification_user:
$myNotifications = DB::table('notification_user')
->join('notifications', 'notifications.id', 'notification_user.notification_id')
->where('notification_user.user_id', $userId)
->where('notification_user.seen', 0)
->get();
the result of $myNotifications is correct but I want to use Model and its relationship instead of DB.
How can I get all records in notifications where each notification related to a specific user which is not seen by the user.
You need to add ->withPivot('seen') to the relationship:
public function users()
{
return $this
->belongsToMany(User::class, 'notification_user', 'notification_id', 'user_id')
->withPivot('seen');
}
Then you can do:
Notification::whereHas('users', function ($q) use ($userId) {
$q->where('id', $userId)->where('seen', 0);
})->get();
To avoid joining users, your other option is whereExists:
Notification::whereExists(function ($q) use ($userId) {
$q
->selectRaw(1)
->table('notification_user')
->whereRaw('notifications.id = notification_user.notification_id')
->where('user_id', $userId)
->where('seen', 0);
})->get();
Should still be more performant, but not much more elegant.
You will have to define the same relation in User model as notifications and then:
$notifications = User::where('id', $user_id)->notifications()->where('seen', 0)->get();
You can use with keyword for eager loading inside your controller.
like if you have any relation defined inside your model, just add a with('modelRelation') before your get() statement in eloquent.
Happy Coding.
I would like to query all models of a hasMany relationship that also have a pivoted relationship with a specified other model.
Example:
Customer:
belongsToMany -> Entry
EntryGroup:
hasMany -> Entry
Entry:
belongsToMany -> Customer
belongsTo -> EntryGroup
The belongsToMany relationship between Customer and Entry is stored in a pivot table.
I now want to collect the relationship to all Entries that belong to a specified Customer on an EntryGroup. Without this filtering restriction, I would have a function like
class EntryGroup extends Model
{
...
public function entries()
{
return $this->hasMany(Entry::class);
}
}
Thanks in advance for any suggestions you might have.
try this one
$customers->entries()->with('entryGroup')->get();
Try This:
<?PHP
$customerId = 5;
Entry::whereHas('customer', function ($query) use ($customerId) {
$query->where('id', $customerId);
})->has("EntryGroup")->get();
This return all the entry has a entrygroup and belong to customer id 5
Try this:
$entryGroup->entries()->whereHas('customer', function ($query) use ($customerId) {
$query->where('customers.id', $customerId);
})->get();
1. users
1. id
2. name
2. categories
1. id
2. category_name
3. user_id
3. posts
1. id
2. post_title
3. category_id
So now I want to show data in my view
like : post_title->category_name->user_name
How to do in laravel query relationship in model
Define the relationships
class Post extends Model
{
return $this->blongsTo(Category::class);
}
class Category extends Model
{
return $this->blongsTo(User::class);
}
Now
$post = with('category.user')->whereId(1)->first(); //1 is my guess
$post->category()->user->name();
Also it seems like a has-many-through relationship though you can access a user's post like this
$user->posts;
For that you need to define:
class User extends Model
{
/**
* Get all of the posts for the user.
*/
public function posts()
{
return $this->hasManyThrough(Post:class, Category::class);
}
}
$Query=DB::select('select posts.post_title,categories.category_name,
users.name from posts,categories,users where users.id=categories.user_id and
categories.id=posts.category_id');
if you dont use DB::
you can use your model
$Query = Users::select('users.name', 'posts.post_title', 'categories.category_name')
->join('categories', function ($join) {
$join->on('categories.user_id', '=', 'users.id')
->join('categories.id', '=', 'posts.category_id');
})
->get();
check spell table name and columns
but if there is duplicate in data it wont work