getting database results from an array of ids [duplicate] - php

I'm trying to execute IN statement in Eloquent query. I tried this:
$id = urldecode($id);
$news = News::whereHas('newsCategories', function($q) use($id)
{
$q->where('category_id', 'IN', '('.$id.')')->orderBy('created_at', 'desc');
})->get();
But I get empty result.
When I switch IN for = and pass a number instead of array I get results. Did I do something wrong?
So this works:
$id = 2;
$news = News::whereHas('newsCategories', function($q) use($id)
{
$q->where('category_id', '=', $id)->orderBy('created_at', 'desc');
})->get();

You want whereIn with an array of your ids to be checked...
$news = News::whereHas('newsCategories', function($q) use($array_of_ids)
{
$q->whereIn('category_id', $array_of_ids)
->orderBy('created_at', 'desc');
})->get();
Just make sure that you're passing in something that is truly an array :)

Related

Can not use where clause after using with clause in Laravel query

I am writing a query using with and then where clause in laravel.
$users = User::query()->with('roles')->where('name', '!=', 'customer')->get();
return $users;
But where clause is not working here. Customers are not excluded. I am providing the snap shot of the query result.
I think you need whereHas() :
use Illuminate\Database\Eloquent\Builder;
$users = User::query()
->with('roles')
->whereHas('roles', function (Builder $query) {
$query->where('name', '!=', 'customer');
})
->get();
return $users;
I suppose you trying to filter relation data in base query.
Try smth like that:
$users = User::query()->with([
'roles' => function ($q) {
$q->where('name', '!=', 'customer');
}])
->get();
return $users;
Doc

Laravel Eloquent hardcoded value in whereNotIn

In Laravel eloquent query using multiple columns for whereNotIn clause I need to hardcoded one of the DB::raw column for the value should be coming from a variable (loop variable). What is the best way to implement this?
This is my query and I need to change the hardcoded 1 in DB::raw('(1,user_profile.user_id')
$otherProfiles = Userprofile::where('user_id', '!=', $profile->user_id)
->where(function ($query) use ($userInterests) {
foreach ($userInterests as $interest) {
$query->orWhere('interest', 'like', "%$interest%");
};
})
->whereNotIn(DB::raw('(1, user_profile.user_id)'), function ($query) {
$query->select('sender_id', 'receiver_id')
->from('email_reports');
})
->inRandomOrder()
->get();
Manage to fix it by just simple concatenation
the code added were DB::raw('('. $profile->user_id . ', user_profile.user_id)')
create a variable as $id for your dynamic value..
$otherProfiles = Userprofile::where('user_id', '!=', $profile->user_id)
->where(function ($query) use ($userInterests) {
foreach ($userInterests as $interest) {
$query->orWhere('interest', 'like', "%$interest%");
};
})
->whereNotIn('user_id', $id), function ($query) {
$query->select('sender_id', 'receiver_id')
->from('email_reports');
})
->inRandomOrder()
->get();

Query array using whereHas

I want to filter products by category (manyToMany relationship). Basically the user select which categories to show. The categories I want to filter are in $request->keywords. This is what I tried:
$products = Product::all();
foreach($request->keywords as $keyword) {
$products = Product::whereHas('categories', function($q) use ($keyword){
$q->where('title', '=', $keyword);
})->get();
}
return response()->json($products);
The problem is that this does not get all the categories, only the products with the last category in the array. I guess at this point: $q->where('title', '=', $keyword);, $q does not keep the results of the last loop iteration but always deletes the last loop results.
I also tried the same thing with $q->orWhere('title', '=', $keyword);, but that actually doesn't give me any results.
Thanks for your help!
Changed your approach to fetch the data,
$products = Product::all();
if (!empty($request->keywords)) { // if keywords not empty
$keyword = $request->keywords;
$products = Product::whereHas('categories', function ($q) use ($keyword) {
$q->whereIn('title', $keyword); // where in for array
})->get(); // it won't override old data as there is no loop
}
return response()->json($products);
You can simply use whereIn on the title field by passing in your keywords.
$products = Product::all();
$titles = [];
foreach($request->keywords as $keyword) {
$titles[] = $keyword;
}
$products = Product::whereHas('categories', function($q) use ($keyword){
$q->whereIn('title', $titles);
})->get();
I'm improving other persons answer. Below is the filtered code here
$builder = new Product;
if($request->filled('keywords')) { // if keywords key has any value then query will execute.
$builder = $builder->whereHas('categories', function($q) use ($request){
$q->whereIn('title', array_values($request->keywords));
});
}
$items = $builder->get();
dd($items);
You can try this.

How to pass an array of IDs from one Laravel query to another

I have 2 queries from two different tables. First one contains the IDs which I would like to use in the second query. For now I do it like this. I extract the IDs into a new array, and then use this array in ->whereIn() in second query.
$campaign = DB::connection('mysql2')->table('mc_spots')
->select('s_customer', 's_product', 'spotid')
->where('s_starttermin', '>=', date("Y-m-d", strtotime($dateFrom)))
->where('s_lastrun', '<=', date("Y-m-d", strtotime($dateUntil)))
->where('s_media', '=', $media)
->where(function ($query) use ($products) {
for ($i = 0; $i < count($products); $i++) {
$query->orwhere('s_product', '=', $products[$i]);
}
})
->get();
$campaignID = [];
foreach ($campaign as $c) {
array_push($campaignID, $c->spotid);
}
$table = DB::connection('mysql2')->table('schaltdaten_tv_de')
->select('*')
->join('epgdata_channel', 'schaltdaten_tv_de.cid', '=', 'epgdata_channel.channelid')
->join('mc_spots', 'schaltdaten_tv_de.ReferenceDescription', '=', 'mc_spots.spotid')
->whereIn('ReferenceDescription', $campaignID)
->groupBy('epgdata_2013.id')
->orderBy('StartofBreak', 'ASC')
->limit(500)
->get();
Is there more convenient way to do this without looping through every item of $campaign?
You need to pluck id from first query which gives you array of ids and you can use it in second query.
$campaign = DB::connection('mysql2')->table('mc_spots')
->select('s_customer', 's_product', 'spotid')
->where('s_starttermin', '>=', date("Y-m-d", strtotime($dateFrom)))
->where('s_lastrun', '<=', date("Y-m-d", strtotime($dateUntil)))
->where('s_media', '=', $media)
->where(function ($query) use ($products) {
for ($i = 0; $i < count($products); $i++) {
$query->orwhere('s_product', '=', $products[$i]);
}
})
->pluck('spotid');
Now, use spot id array in whereIn of second as ,
$table = DB::connection('mysql2')->table('schaltdaten_tv_de')
->select('*')
->join('epgdata_channel', 'schaltdaten_tv_de.cid', '=', 'epgdata_channel.channelid')
->join('mc_spots', 'schaltdaten_tv_de.ReferenceDescription', '=', 'mc_spots.spotid')
->whereIn('ReferenceDescription', $campaign)
->groupBy('epgdata_2013.id')
->orderBy('StartofBreak', 'ASC')
->limit(500)
->get();
Hope you understand
You can do it like this
$campaignID = $campaign->pluck('spotid');
Pluck doc:
The pluck method retrieves all of the values for a given key
And as Sagar said, it retrieves an array which is the second argument to our ->whereIn()
You can do this by use of array_column()
Like this
$campaignID=array_column($campaign,'spotid')
Make sure that $campaign must be an array. if it is object the convert it into array like this json_decode(json_encode($campaign),true)
For exapmle
$t='[{"id":49},{"id":61},{"id":5},{"id":58}]' ;
array_column(json_decode($t,true),'id')
It will give output as
As you're already joining the mc_spots table in the 2nd query you could always just add the same constraints from the 1st query:
$table = DB::connection('mysql2')->table('schaltdaten_tv_de')
->select('*')
->join('epgdata_channel', 'schaltdaten_tv_de.cid', '=', 'epgdata_channel.channelid')
->join('mc_spots', 'schaltdaten_tv_de.ReferenceDescription', '=', 'mc_spots.spotid')
->where('mc_spots.s_starttermin', '>=', \Carbon\Carbon::parse($dateFrom))
->where('mc_spots.s_lastrun', '<=', \Carbon\Carbon::parse($dateUntil))
->where('mc_spots.s_media', $media)
->whereIn('s_product', $products)
->groupBy('epgdata_2013.id')
->orderBy('StartofBreak', 'ASC')
->limit(500)
->get();
Hope this helps!

whereHas query in Laravel

Hello guys,
$filterArray = explode("_", $filters);
$data['articles'] = \DB::table('products')->join('product_category', function ($q) {
$q->on('product_category.product_id', '=', 'products.id');
})->where('product_category.category_id', '=', $id)
->select('products.*')
->whereBetween('price_retail_1', array($priceFrom, $priceTo))
->whereHas('filters', function ($query, $filterArray) {
$query->whereIn('filter_id', $filterArray);
})
->orderBy('products.' . $sort, $sortOrder)
->get();
}
I have the following query and I'm having some issues on the whereHas method. I'm getting an error
Unknown column 'has' in 'where clause
most likely because the $filterArray variable is out of scope for the function ( or at least that is what I am guessing. Any help on how to solve the issue is appreciated.
You cannot use whereHas method in the Query Builder context. The whereHas method is only for Eloquent Query Builder that is comming from the Eloquent models and their relationships.
What you can do is to use joins. So you can try like this:
$filterArray = explode("_", $filters);
$data['articles'] = \DB::table('products')->join('product_category', function ($q) {
$q->on('product_category.product_id', '=', 'products.id');
})->where('product_category.category_id', '=', $id)
->select('products.*')
->whereBetween('price_retail_1', array($priceFrom, $priceTo))
->join('filters', 'products.filter_id', '=', 'filters.filter_id')
->whereIn('filter_id', $filterArray);
->orderBy('products.' . $sort, $sortOrder)
->get();
I don't know how you connecting these two tables so here is only the example data:
->join('filters', 'products.filter_id', '=', 'filters.filter_id')

Categories