I'm having problems accessing the Pivot relationship.
#relations: array:1 [
"orders_material" => Collection {#250
#items: []
}
]
I want to get the orders_material that have pivot values null
This is the query :
$material = Material::with(['orders_material' => function($query) use ($begin_date, $end_date, $begin_hour, $hour_final)
{
$query->whereBetween('Orders_has_Material.date_begin',[$begin_date, $end_date])
->whereBetween('Orders_has_Material.date_final',[$begin_date, $end_date])
->where('Orders_has_Material.Material_id', null)
->where('Orders_has_Material.Orders_id', null);
}])
->get();
dd($material);
public function orders_material()
{
return $this->belongsToMany('App\Orders', 'Orders_has_Material', 'Material_id', 'Orders_id');
}
First of all, as I see here u have many columns in ur pivot table like date_begin and date_final so here u need to edit ur relationship models like this :
public function orders_material()
{
return $this->belongsToMany('App\Orders', 'Orders_has_Material', 'Material_id', 'Orders_id')->withPivot('date_begin', 'date_final', 'column3');
}
and to access to them just u need to get $material of orders or the inverse.
which means, as u get the $material in ur query, i think to want to access to the orders related to that $material and show up some information inside ur pivot table. u can access to them like this (if ur relationship models are correct of course):
foreach($material->orders as $order)
{
echo $order->pivot->date_begin;
echo $order->pivot->date_final;
}
for more information read the doc many to many laravel with pivot table
Related
i have 2 models order and city and each order has one city now what i want to do is to show the user how many orders per each city he has . and the result for example would be some thing like below :
Illuminate\Support\Collection {#2220 ▼
#items: array:17 [▼
"new-york" => 80
"city-number2" => 20
"city-number3" => 10
"city-number4" => 5
]
}
what i have tried so far is to work with the laravels withcount on order like below :
$orders = Order::withCount('orders')->where('shop_id', $shop->id)->get();
but no luck with it because it returns the count of all cities not each city individually .
thanks in advance
You can do this query from the other direction easily:
$cities = City::withCount(['orders' => fn ($q) => $q->where('shop_id', $shop->id)])->get();
foreach ($cities as $city) {
echo "{$city->name}: {$city->orders_count}";
}
If you need to restrict which cities are listed you can constrain that further if needed.
this problem is based on one to many relationships in DBMS, in laravel there is an inbuild option that comes with eloqut (one city has many orders and one order belongs to one city)
first of all, you need to implement the cities model and order model
inside cities model define a function like this
public function orders()
{
return $this->belongsTo(Order::class, 'city_id');
}
and in order model define a function like this
public function city()
{
return $this->hasMany(City::class, 'order_id');
}
then in the controller to find how many orders per each city use the query like this with laravel eloquent
$cities= City::withCount(['orders' => fn ($q) => $q->where('shop_id', $shop->id)])->get();
foreach ($cities as $city) {
echo $city->orders_count;
}
The withCount method which will place a {relation}_count attribute on the resulting models:
the controller to find how many orders per each city use the query like this with laravel eloquent.
$orders = Order::with('cities')
->select('city_id',\DB::raw('count(*) as city'))
->groupby('city_id')
->get();
I want to get specific column from Model relation in Laravel, but the relation model returning empty array.
Eloquent Query
$medicines = Medicine::with(['weightage' => function($query) {
$query->select('name');
}])->get(['name', 'description']);
Medicine Modal
public function weightage()
{
return $this->hasMany('App\MedicineWeightage', 'medicine_id');
}
You always need to also select the primary and foreign keys of the table to make the relation work:
$medicines = Medicine::with(['weightage' => function($query) {
$query->select(['id', 'name', 'medicine_id']);
}])->get(['id', 'name', 'description']);
I'm trying to retrieve a user's answer. I have this query :
$data = Category::where('id', $id)->with(
[
'questions' => function ($query) {
$query->with(['answers' => function ($query) {
$query->where( 'user_id', auth()->user()->id )->first();
} ])->orderBy('position', 'ASC');
}
]
)->first();
I would like to collect only the answer (a user can only have one answer to a question)
But laravel returns an array "answers"
How to have only the answer, without this array? Thank you !
You can define another relationship called answer and make it a hasOne. This way you only get 1 result, however note that without an order (order by) the result can change from request to request.
I have three tables: users, organizations, organization_user. organization_user is a pivot table for the many-to-many relationship between users and organizations. The many-to-many relationships have been setup correctly in the corresponding models.
I need to obtain all users who are not associated with a given organization. How should this be done using eloquent. Below is what I have tried, but it is returning no results:
public function associate_user($organization_id){
$data = [
'organization' => \App\Organization::find($organization_id),
'users' => \App\User::whereDoesntHave('organizations', function($query) use ($organization_id){
$query->where('organization_id', $organization_id);
})
];
return view('admin.associateUser', $data);
}
You are never actually executing the query.
You need to call get() at the end of the query builder.
public function associate_user($organization_id) {
$data = [
'organization' => \App\Organization::find($organization_id),
'users' => \App\User::whereDoesntHave('organizations', function($query) use ($organization_id){
$query->where('organization_id', $organization_id);
})->get(); // Add the call to get()
];
return view('admin.associateUser', data);
}
In my Database, I have:
tops Table
posts Table
tops_has_posts Table.
When I retrieve a top on my tops table I also retrieve the posts in relation with the top.
But what if I want to retrieve these posts in a certain order ?
So I add a range field in my pivot table tops_has_posts and I my trying to order by the result using Eloquent but it doesn't work.
I try this :
$top->articles()->whereHas('articles', function($q) {
$q->orderBy('range', 'ASC');
})->get()->toArray();
And this :
$top->articles()->orderBy('range', 'ASC')->get()->toArray();
Both were desperate attempts.
Thank you in advance.
There are 2 ways - one with specifying the table.field, other using Eloquent alias pivot_field if you use withPivot('field'):
// if you use withPivot
public function articles()
{
return $this->belongsToMany('Article', 'tops_has_posts')->withPivot('range');
}
// then: (with not whereHas)
$top = Top::with(['articles' => function ($q) {
$q->orderBy('pivot_range', 'asc');
}])->first(); // or get() or whatever
This will work, because Eloquent aliases all fields provided in withPivot as pivot_field_name.
Now, generic solution:
$top = Top::with(['articles' => function ($q) {
$q->orderBy('tops_has_posts.range', 'asc');
}])->first(); // or get() or whatever
// or:
$top = Top::first();
$articles = $top->articles()->orderBy('tops_has_posts.range', 'asc')->get();
This will order the related query.
Note: Don't make your life hard with naming things this way. posts are not necessarily articles, I would use either one or the other name, unless there is really need for this.
For Laravel 8.17.2+ you can use ::orderByPivot().
https://github.com/laravel/framework/releases/tag/v8.17.2
In Laravel 5.6+ (not sure about older versions) it's convenient to use this:
public function articles()
{
return $this->belongsToMany('Article', 'tops_has_posts')->withPivot('range')->orderBy('tops_has_posts.range');
}
In this case, whenever you will call articles, they will be sorted automaticaly by range property.
In Laravel 5.4 I have the following relation that works fine in Set model which belongsToMany of Job model:
public function jobs()
{
return $this->belongsToMany(Job::class, 'eqtype_jobs')
->withPivot(['created_at','updated_at','id'])
->orderBy('pivot_created_at','desc');
}
The above relation returns all jobs that the specified Set has been joined ordered by the pivot table's (eqtype_jobs) field created_at DESC.
The SQL printout of $set->jobs()->paginate(20) Looks like the following:
select
`jobs`.*, `eqtype_jobs`.`set_id` as `pivot_set_id`,
`eqtype_jobs`.`job_id` as `pivot_job_id`,
`eqtype_jobs`.`created_at` as `pivot_created_at`,
`eqtype_jobs`.`updated_at` as `pivot_updated_at`,
`eqtype_jobs`.`id` as `pivot_id`
from `jobs`
inner join `eqtype_jobs` on `jobs`.`id` = `eqtype_jobs`.`job_id`
where `eqtype_jobs`.`set_id` = 56
order by `pivot_created_at` desc
limit 20
offset 0
in your blade try this:
$top->articles()->orderBy('pivot_range','asc')->get();
If you print out the SQL query of belongsToMany relationship, you will find that the column names of pivot tables are using the pivot_ prefix as a new alias.
For example, created_at, updated_at in pivot table have got pivot_created_at, pivot_updated_at aliases. So the orderBy method should use these aliases instead.
Here is an example of how you can do that.
class User {
...
public function posts(): BelongsToMany {
return $this->belongsToMany(
Post::class,
'post_user',
'user_id',
'post_id')
->withTimestamps()
->latest('pivot_created_at');
}
...
}
You can use orderBy instead of using latest method if you prefer. In the above example, post_user is pivot table, and you can see that the column name for ordering is now pivot_created_at or pivot_updated_at.
you can use this:
public function keywords() {
return $this->morphToMany(\App\Models\Keyword::class, "keywordable")->withPivot('order');
}
public function getKeywordOrderAttribute() {
return $this->keywords()->first()->pivot->order;
}
and append keyword attribiute to model after geting and use sortby
$courses->get()->append('keyword_order')->sortBy('keyword_order');