issue in laravel relationship with multiple model - php

user has relation with creater one to one but creater has relation with archive belongsToMany
$creatorQuery = User::query();
$cultivator_id = 2;
$creatorQuery = $creatorQuery->select('id', 'name', 'email', 'role');
$creatorQuery = $creatorQuery->with('creater', function($q) {
$q->whereHas('archive', function($q) use($cultivator_id) {
$query->where('caltivater_id', $cultivator_id);
});
});
$creators = $creatorQuery->get();
showing error mb_strpos() expects parameter 1 to be string, object given

function is supposed to be passed into creater, so you need to change your call to be a key/value array:
$creatorQuery = $creatorQuery->with(['creater' => function($q) use($cultivator_id) {
$q->whereHas('archive', function($q) use($cultivator_id) {
$query->where('caltivater_id', $cultivator_id);
});
}]);

You've said you want to get users by their caltivater_id value defined in Archive model. Use nested whereHas():
$creators = User::whereHas('creator', function($q) use($cultivator_id) {
$q->whereHas('archive', function($q) use($cultivator_id) {
$q->where('caltivater_id', $cultivator_id);
});
})
->with('creators')
->get();
Or use dot notation:
$creators = User::whereHas('creator.archive', function($q) use($cultivator_id) {
$q->where('caltivater_id', $cultivator_id);
})
->with('creators')
->get();

Related

Find record either belong the main table or to the relationship eloquent ORM

User table has first_name and the teacherSubjects have subject, i wan to put a condition in such a way if it matches to either the firstname in the User table or the subject in the teacherSubject
$teachers = User::with('teacherSubject')->whereHas('teacherSubject', function ($query) use($conditions){
$query->where($conditions);
})->get();
Try this way:
$teachers = User::with('teacherSubject')
->where(function($query) use($name) {
$query->where('first_name',$name);
->orWhereHas('teacherSubject', function ($query1) use($name){
$query1->where('subject',$name);
});
})
->get();
You can try like this,
$teachers = User::where(function($sub) use($name) {
$sub->where('first_name', $name)
->orWhereHas('teacherSubject', function($s) use($name) {
$s->where('subject', $name);
});
})whereHas('teacherSubject', function ($query) use($conditions){
$query->where($conditions);
})->with('teacherSubject')->get();
Here $name is the first name to be searched.

Filtering in Laravel using regex

I'm trying to filter products based on query string. My goal is to get products from a collection if it's given, otherwise get every product. Could someone help me what's wrong with the following code?
$products = \App\Product::where([
'collection' => (request()->has('collection')) ? request('collection') : '[a-z]+',
'type' => (request()->has('type')) ? request('type') : '[a-z]+'
])->get();
PS.: I've also tried with 'regex:/[a-z]+', it's not working...
$products = \App\Product::where(['collection' => (request()->has('collection')) ? request('collection') : 'regex:/[a-z]+'])->get();
What you can do is use when eloquent clause, so your where clause for collections will be triggered only when the request('collection') exists, same logis applie to type as well.
$products = \App\Product::
when(request()->has('collection'), function ($q) {
return $q->where('collection', request('collection'));
});
->when(request()->has('type'), function ($q) {
return $q->where('type', request('type'));
})
->get();
Or another way if you have your request values assigned to a variable something like:
$collection = request('collection');
$type= request('type');
$products = \App\Product::
when(!empty($collection), function ($q) use ($collection) {
return $q->where('collection', $collection);
});
->when(!empty($type), function ($q) use ($type) {
return $q->where('type', $type);
})
->get();

laravel query join with only latest record

I'm using Laravel 5.3 and trying to return a heist with it's product and only the latest order and with the latest price history. Both joins don't return anything but if I remove the $q->latest()->first(); and replace it with a simple orderBy() I get all results. My query is:
$data = $heist->with(['product'=> function($query) {
$query->with(['orders' => function($q) {
return $q->latest()->first();
}]);
$query->with(['price_history' => function($q) {
return $q->latest()->first();
}]);
}])->orderBy('completed_at', 'DESC')->orderBy('active', 'DESC')->get();
As discussed in the comments, I believe the simplest way of doing this is
$heists = $heist->with(['product'=> function($query) {
$query->with([
'orders' => function($q) {
return $q->orderBy('created_at', 'desc')->take(1)->get();
},
'price_history' => function($q) {
return $q->orderBy('created_at', 'desc')->take(1)->get();
}
]);
}])->orderBy('completed_at', 'desc')->orderBy('active', 'desc')->get();
Hope this helps :)
Calling first() is the same as calling take(1)->get()[0];
Which means limit the amount returned to 1 and return it. What you want is just the limit part. So if you change first() to take(1).
Update
$data = $heist->with([
'product'=> function($query) {
$query->with(
[
'orders' => function($q) {
$q->latest()->take(1);
},
'price_history' => function($q) {
$q->latest()->take(1);
}
]
);
}
])->orderBy('completed_at', 'DESC')->orderBy('active', 'DESC')->get();

Selecting required fields using relations in Laravel

I have a model Meetings like this:
public function meeting_comments(){
return $this->hasMany('App\MeetingsComments', 'meeting_id', 'id');
}
public function meeting_users() {
return $this->hasMany('App\UserMeetingDetails', 'meeting_id', 'id');
}
The Controller is like this:
$res = Meetings::with('meeting_comments', 'meeting_users')
->select('')->get()->toArray();
I only need comments from meeting_comments and user_id from meeting_users.
What do I put in select to only get the required fields from meeting_comments and meeting_users ??
You do it through a closure in the with call:
$res = Meetings::with(['meeting_comments' => function($query) {
$query->select('comments', 'meeting_id');
}, 'meeting_users' => function($query) {
$query->select('user_id', 'meeting_id');
}])
->get()->toArray();
I'm taking this from memory, so the syntax may be slightly incorrect, but it should work. :)

whereHas not working as expected

I am trying to get all Shops that have one of $item_ids = array('1', '17');.
However, the code below is not doing that as I expected it to - it just hands me all the shops.
$shops = Shop::whereHas('items', function($query) use ($item_ids) {
$query->where('items.id', '=', $item_ids[0]);
foreach(array_slice($item_ids, 1) as $item_id) {
$query->orWhere('items.id', '=', $item_id);
}
})
->get(array('shops.id', 'shops.shop_name', 'shops.lat', 'shops.lng'));
I do I only get the Shops with one of the specified Items?
You should rather use:
$shops = Shop::whereHas('items', function($query) use ($item_ids) {
$query->whereIn('id', $items_ids);
})->get();
or
$shops = Shop::whereHas('items', function($query) use ($item_ids) {
$query->whereIn('id', $items_ids);
})->select('shops.id', 'shops.shop_name', 'shops.lat', 'shops.lng')->get();

Categories