"message": "Call to undefined method Closure::getRelationExistenceQuery()", laravel - laravel

I have created a function to get data from db but the function returns an error when i test with postman.
public function payments(){
$data = Investigations::whereHas(function($query){
$query->where('name', 'LIKE', '%consultation%' );
})->get();
return $data;
}
The table has these columns
protected $fillable = [
"visit", "admission_id", "type", "procedure", "quantity", "price", "discount",
"amount", "user", "instructions", "ordered", "invoiced", "reasons", "assigned_to",
"performing_doctor", "on_credit", "comments", "credit_status", "is_walkin",
'service_sale_id', "cancelled", 'cancel_text', "date_changed_by", "date_adjusted_from",
"assigned_by", "assigned_on",
'moved_from_chargesheet', 'package_id',
"created_at",
];

I can't see there is a "name" column.
'whereHas' used to query in a relation
Investigations::whereHas('relation_name', function($query){
$query->where('name', 'LIKE', '%consultation%' );
})->get();
If you want to search in the current table, you can use 'where'.
it can be a condition or a function
Investigations::where('name', 'LIKE', '%consultation%' )->get()
 
Investigations::where(function($query){
$query->where('name', 'LIKE', '%consultation%' );
})->get()

Related

Filter relation using parameter on model - Laravel 9

I have a model with relations, and need to filter this relations depending on request parameter.
On controller I get all properties with his owners (a property can have several owners, and vice versa).
Property controller:
$property= Property::query()
->when($request->search, function($query, $search) {
$query->where('name','like', '%'.$search.'%')
->orWhere('name2','like', '%'.$search.'%')
->orWhere('city','like', '%'.$search.'%');
})
->select(['id', 'name', 'published'])
->with(['photo', 'owner', 'destiny'])->get();
And in property model:
public function owner(){
return $this->belongsToMany(
Owner::class,
'rel_owners_properties'
)->select(['owner.id', 'owner.nombre', 'owner.nombre_empresa']);
}
Now, if I have a $request->ownerId value in controller, I need to filter only the properties that this owner has.
I have tried with something like this, but I receive all the properties without any owner:
$property= Property::query()
->when($request->search, function($query, $search) {
$query->where('name','like', '%'.$search.'%')
->orWhere('name2','like', '%'.$search.'%')
->orWhere('city','like', '%'.$search.'%');
})
->select(['id', 'name', 'published'])
->with([
'photo',
'owner' => function ($query) use ($request) {
$query->where(['owner_id' => $request->ownerId]);
},
'destiny'
])->get();
To filter by a relationship you need to use whereHas:
$property = Property::query()
->when($request->search, function ($query, $search) {
$query->where('name', 'like', '%' . $search . '%')
->orWhere('name2', 'like', '%' . $search . '%')
->orWhere('city', 'like', '%' . $search . '%');
})
->select(['id', 'name', 'published'])
->whereHas('owner', function ($query) use ($request) {
$query->where('id', $request->ownerId);
});
->with([
'photo',
'owner'
'destiny'
])->get();

How to group where clauses in Laravel Query Builder correctly

I am running the following query using the search() function below - the problem is I need to group the where clauses - what am I doing wrong?
select `standings`.*, `users`.`name` as `user` from `standings`
left join `users` on `standings`.`user_id` = `users`.`id`
where `users`.`name` like '%bob%' or `users`.`email` like '%bob%'
and `standings`.`tenant_id` = '1'
In my Standings model I have the following search() that performs the WHERE clause
public static function search($query)
{
return empty($query) ? static::query()
: static::where('users.name', 'like', '%'.$query.'%')
->orWhere('users.email', 'like', '%'.$query.'%');
}
public function render()
{
$query = Standing::search($this->search)
->select('standings.*', 'users.name AS user')
->leftJoin('users', 'standings.user_id', '=', 'users.id')
->orderBy('points', 'desc')
->orderBy('goals_difference', 'desc')
->orderBy('goals_for', 'desc');
if($this->super && $this->selectedTenant) {
$query->where('standings.tenant_id', $this->selectedTenant);
}
return view('livewire.show-standings', [
'standings' => $query->paginate($this->perPage)
]);
}
The query works however it doesn't group the WHERE clause correctly on the users.name & users.email fields - how do I change this search() function so the WHERE query has them grouped like this
where (`users`.`name` like '%bob%' or `users`.`email` like '%bob%')`
You need to group the where clauses in a wrapping where clause. Try this
public static function search($query)
{
return empty($query)
? static::query()
: static::where(function($query){
$query->where('users.name', 'like', '%'.$query.'%')
->orWhere('users.email', 'like', '%'.$query.'%');
});
}
Thanks that for some reason even though looks correct gives me the following error - Object of class Illuminate\Database\Eloquent\Builder could not be converted to string NB I am using Laravel with Livewire (not sure if that should make any difference)
$query->where('users.name', 'like', '%'.$query.'%') and ->orWhere('users.email', 'like', '%'.$query.'%'); is giving the error because while trying to compare $query is being treated as a string hence the error
You can define the search as a query scope on the model
//Assuming a relation Standing belongsTo User
//Query constraint to get all Standing records where
//related User record's name or email are like searchTerm
public function scopeSearch($query, string $searchTerm)
{
return $query->whereHas('user', function($query) use($searchTerm){
$query->where('name', 'like', "%{$searchTerm)%")
->orWhere('email', 'like', "%{$searchTerm}%");
});
}
Laravel docs:https://laravel.com/docs/8.x/eloquent#local-scopes
With the above search scope defined on Standing model, you can have the render function as
public function render()
{
$query = Standing::with('user:id,name')
->search($this->search)
->orderBy('points', 'desc')
->orderBy('goals_difference', 'desc')
->orderBy('goals_for', 'desc');
if($this->super && $this->selectedTenant) {
$query->where('tenant_id', $this->selectedTenant);
}
return view('livewire.show-standings', [
'standings' => $query->paginate($this->perPage)
]);
}

How to send a separate array inside Laravel eloquent with function?

I have written as below in my code in LineSheet controller and the items function is in LineSheet model, and I have an array call $seasons. Now I need to send this $seasons array with items
LineSheet Controller:
$linesheetItems = LineSheetItem::select('linesheet_id', 'items.season', 'items.amt_item')
->join('items', function ($join) {
$join->on('items.amt_item', '=', 'linesheet_items.item_code');
$join->on('items.company', '=', 'linesheet_items.company');
$join->on('items.division', '=', 'linesheet_items.division');
})
->where('linesheet_items.linesheet_id', '=', $id)
->groupBy('items.amt_item', 'items.season')
->get();
foreach ($linesheetItems as $linesheetItem) {
$seasons[] = Season::where('code', $linesheetItem['season'])->first();
}
$linesheet = LineSheet::where('linesheet.id', '=', $id)
->select('linesheet.*')->with(['items', 'creator:id,username', 'updater:id,username'])
->first();
LineSheet Model:
public function items()
{
return $this->hasMany('\App\Models\LineSheetItem', 'linesheet_id', 'id')
->join('items', function ($join) {
$join->on('items.amt_item', '=', 'linesheet_items.item_code');
$join->on('items.company', '=', 'linesheet_items.company');
$join->on('items.division', '=', 'linesheet_items.division');
})
->join('inventory_items', function ($join) {
$join->on('inventory_items.item', '=', 'linesheet_items.item_code');
$join->on('inventory_items.company', '=', 'linesheet_items.company');
$join->on('inventory_items.division', '=', 'linesheet_items.division');
})
->select('linesheet_items.linesheet_id', 'items.id', 'items.amt_item', 'items.image_name',
'items.company', 'items.division', 'items.color_description', 'items.item_description',
'items.season', 'items.wholesale_price', 'items.retail_price', 'items.color_code',
'items.vendor_desc', 'items.vendor_code', 'inventory_items.on_hand', 'inventory_items.cost',
'items.brand', 'items.category_code', 'items.category', 'items.fabric_code', 'items.fabric_desc')
->groupBy('linesheet_items.item_code', 'linesheet_items.company', 'linesheet_items.division');
}
with items I need to attach my $seasons array also and get a response as below
I expect a final output as below:
"items": [
{
"linesheet_id": 44,
"id": 61,
"amt_item": "PS839730WT",
"image_name": "image_name",
"company": "01",
"division": "PAP",
"color_description": "colordes1",
"item_description": "itemdes1",
"season": "S1",
"wholesale_price": "100",
"retail_price": "100",
"color_code": "colorcode1",
"vendor_desc": "vendor_desc",
"vendor_code": "vendor_code",
"on_hand": "40",
"cost": "3.70",
"brand": "brand",
"category_code": "category",
"category": "category1",
"fabric_code": "code1",
"fabric_desc": "fabric_desc",
seasons: [
//array elements
]
}
]
How to achieve this?
You can use belongsTo relationship and then eager load them. A LineSheetItem seems to belong to a Session.
So you can do LineSheetItem::with('season')->get().
https://laravel.com/docs/8.x/eloquent-relationships#one-to-many-inverse
https://laravel.com/docs/8.x/eloquent-relationships#eager-loading

Laravel with where like condition in relationship

I have a WorkPackage model with below relationship.
public function work_items()
{
return $this->hasMany(WorkItem::class);
}
And WorkPackage has 'title','project_id' columns and work_items has 'title','work_package_id' columns. Now I want to search user typed keyword is matching with title in both table.
Here is my tried function
public function getWorkPackageProposals($projectId, $title)
{
$result['data'] = $this->workPackage->with(['work_items' => function ($query) {
$query->where('title', 'LIKE', "%{$title}%");
}])
->where('project_id', $projectId)
->where('title', 'LIKE', "%{$title}%")
->get();
return $result;
}
but its not working.
Please find the below code for I used to create object of WorkPackage.
public function __construct(WorkPackage $workPackage)
{
$this->workPackage = $workPackage;
$this->setModel(WorkPackage::class);
$this->workItemRepository = app(WorkItemRepository::class);
}
whereHas() works to specify additional filters for the related model to check :
$result['data'] = $this->workPackage->whereHas('work_items', function ($query) use ($title) {
$query->where('title', 'LIKE', "%{$title}%");
})
->where('project_id', $projectId)
->where('title', 'LIKE', "%{$title}%")
->get();
return $result;
Below code works for me. Thanks to everyone for help to get right answer.
$result['data'] = $this->workPackage->with(['work_items' => function ($q) use ($title) {
$q->where('title', 'LIKE', "%{$title}%");
}])
->where('project_id', $projectId)
->where('title', 'LIKE', "%{$title}%")
->get();
return $result;
I think your problem will be solved with join method:
$result = $this->workPackage
->join('work_items', 'work_packages.id', '=', 'work_items.package_id')
->where('work_items.title', 'LIKE', '%{$term}%')
->orWhere('work_packages.title', 'LIKE', '%{$term}%')
->get();

How to wrap Eloquent query with parenthesis when we use a conditional clauses in Laravel 5.7

I have a query that should load all the posts with just their english translation.
If the user enter a keyword it return just the english post with a title containing that keyword.
if ($searchKeywords||$searchCategory){
$posts = Post::
select('post_translations.post_id AS id', 'post_translations.title AS title', 'category_id', 'locale')
->join('post_translations', 'posts.id', '=', 'post_translations.post_id')
->where(‘post_translations.locale','=','en')
->when($searchKeywords, function ($query, $searchKeywords) {
return $query->where('post_translations.title', $searchKeywords)->orWhere('post_translations.title', 'like', '%' . $searchKeywords . '%');
})
->when($searchCategory, function ($query, $searchCategory) {
return $query->where('category_id', '=', $searchCategory);
->paginate(20);
}
else
$posts = Post::select('id', 'title', 'category_id')->orderBy('title')->paginate(20);
The generated query is this one:
SELECT `post_translations`.`post_id` AS `id`, `post_translations`.`title` AS `title`, `category_id`
FROM `posts` inner join `post_translations`
ON `posts`.`id` = `post_translations`.`post_id`
WHERE `post_translations`.`locale` = 'en'
AND `post_translations`.`title` = 'About'
OR `post_translations`.`title` like 'About’
LIMIT 20 OFFSET 0
That return me all the 3 posts translations of the post About.
This because of the orWhere.
How can I change the eloquent query in order to generate a query like this?
SELECT `post_translations`.`post_id` AS `id`, `post_translations`.`title` AS `title`, `category_id`
FROM `posts` inner join `post_translations`
ON `posts`.`id` = `post_translations`.`post_id`
WHERE `post_translations`.`locale` = 'en'
AND (`post_translations`.`title` = ‘About' OR `post_translations`.`title` like 'About’ )
LIMIT 20 OFFSET 0
The question is not a duplicate of this one because I have one more level of subquery.
How do you wrap Laravel Eloquent ORM query scopes in parentheses when chaining?
Add both condition inside a where query like this:
if ($searchKeywords) {
$posts = Post::select('post_translations.post_id AS id', 'post_translations.title AS title', 'category_id', 'locale')
->join('post_translations', 'posts.id', '=', 'post_translations.post_id')
->where(‘post_translations.locale','=','en')
->where(function ($query) use ($searchKeywords) {
$query->where('post_translations.title', $searchKeywords)
->orWhere('post_translations.title', 'like', '%' . $searchKeywords . '%');
})
->paginate(20);
}
I have solved with this code:
if ($searchKeywords||$searchCategory){
$posts = Post::
select('post_translations.post_id AS id', 'post_translations.title AS title', 'category_id', 'locale')
->join('post_translations', 'posts.id', '=', 'post_translations.post_id')
->when($searchKeywords, function ($query, $searchKeywords) {
return $query->where('post_translations.locale','=','en')
->where(function ($query) use ($searchKeywords) {
$query->where('post_translations.title', $searchKeywords)->orWhere('post_translations.title', 'like', '%' . $searchKeywords . '%');
});
})
->when($searchCategory, function ($query, $searchCategory) {
return $query->where('post_translations.locale','=','en')
->where(function ($query) use ($searchCategory) {
$query->where('category_id', '=', $searchCategory);
});
})
->paginate(20);
}
else
$posts = Post::select('id', 'title', 'category_id')->orderBy('title')->paginate(20);

Resources