Combining two collections and paginating them - laravel

So I have ads in a database.
There are 3 types for the ads. Featured, bold and free.
I want to display them in a page. First based on what category has been selected.
I want to show all featured first by added date and then after that all bold and free items by added date. And I want to paginate them.
I have tried this:
$adsFeatured = Ads::where('category', '=', $category)->where('status', 'enabled')->where('type', 'featured')->get();
$adsOther = Ads::where('category', '=', $category)->where('status', '=', 'enabled')->where('type', '=', 'free')->orWhere('type', '=', 'bold')->get();
$adsOther->merge($adsFeatured);
$adsFeatured->paginate(15);
But ofcourse it cannot be paginated if I use get(), but if i dont use it then i cant merge them, i want to merge them because i hope it would place them in that order.
Thanks for help, and I hope I have explained everything properly. :)

You should be able to do that in one query. Try this
$ads = Ads::selectRaw('*, IF(type = "featured",1,0) AS is_featured')
->where('category', $category)
->where('status', 'enabled')
->orderBy('is_featured', 'desc')
->orderBy('created_at', 'desc')
->paginate(15);

Related

Laravel shows more pages in results

I'm working with a query where the results finish on page 21, but I'm getting 29 pages of links. My problem might be a groupBy() problem, but I don't know how to do it.
$afiliates = DB::table('ad_afiliado as af')
->select('af.logo_url', 'af.NombreComercial', 'af.Destacado',
'af.id_afiliado', 'af.Clave')
->join('af_promocion as promo', function ($join) {
$join->on('af.Clave', '=', 'promo.id_afiliado');
})
->where('promo.v_fin', '>', $FechaActual)
->where('af.Activo', '=', 'S')
->where('af.Categoria', 'like', $categoryStr)
->orderBy('af.NombreComercial')
->orderBy(DB::raw('RAND()'))
->distinct()
->paginate(9);
I found the answer. It seems to be an issue with laravel distinct() and pagination, especialy when making joins.
The thread is here:
distinct() with pagination() in laravel 5.2 not working
I had to add the field name was causing repetition of results, to the distinct() and paginate().
In my case 'promo.id_afiliado'
as you'll see in the code next
$afiliates = DB::table('ad_afiliado as af')
->join('af_promocion as promo', 'af.Clave', '=', 'promo.id_afiliado')
->select('af.logo_url', 'af.NombreComercial', 'af.Destacado', 'af.id_afiliado', 'af.Clave')
->where('promo.v_fin','>',$FechaActual)
->where('af.Activo','=', 'S')
->distinct('promo.id_afiliado')
->orderBy('af.Destacado', 'desc')
->orderBy('af.NombreComercial')
->paginate(9, 'promo.id_afiliado');
Thaks #TimLewis for caring, hope this will usefull to others.

Product filtering problems with Laravel Query Builder

I try to implement ajax based filtering in my ecommerce project homepage for searching a product. I am using Laravel Query Builder. My Query for filtering products is given below-
$result= DB::table('products')
->leftjoin('products_description','products.products_id','products_description.products_id')
->leftjoin('image_categories', 'products.products_image', '=', 'image_categories.image_id')
->leftjoin('products_to_categories','products.products_id','products_to_categories.products_id')
->leftjoin('categories','products_to_categories.categories_id','categories.categories_id')
->when($category_slug, function($q) use ($category_slug) {
return $q->where('categories.categories_slug', $category_slug);
})
->where('products_name','like',"%{$querval}%")
->where('image_categories.image_type','=','ACTUAL')
->orderby('products.products_id','DESC')
->take(5)
->get();
I get every product twice in search result. don't know why. A sample response is given in this picture.
Can anyone help me to optimize my query for getting the desired result?
join with categories table only when you have to.
and select your columns strictly. then group by selected columns.
$result= DB::table('products')
->leftjoin('products_description','products.products_id','products_description.products_id')
->leftjoin('image_categories', 'products.products_image', '=', 'image_categories.image_id')
->when($category_slug, function($q) use ($category_slug) {
return $q->leftjoin('products_to_categories','products.products_id','products_to_categories.products_id')
->leftjoin('categories','products_to_categories.categories_id','categories.categories_id')
->where('categories.categories_slug', $category_slug);
})
->where('products_name','like',"%{$querval}%")
->where('image_categories.image_type','=','ACTUAL')
->orderby('products.products_id','DESC')
->select(['products_name','products.id','image_path'])
->groupBy(['products_name','products.id','image_path'])
->take(5)
->get();
you can use from groupBy to avoid comming repeated data.
try this one:
$result= DB::table('products')
->leftjoin('products_description','products.products_id','products_description.products_id')
->leftjoin('image_categories', 'products.products_image', '=', 'image_categories.image_id')
->when($category_slug, function($q) use ($category_slug) {
return $q->where('categories.categories_slug', $category_slug);
})
->where('products_name','like',"%{$querval}%")
->where('image_categories.image_type','=','ACTUAL')
->orderby('products.products_id','DESC')
->groupBy('products_name','products.products_id')
->take(5)
->get();

Finding a user with highest post created in last 24 hours, laravel Eloquent

How to find the user with the highest post created in the last 24 hours in laravel?
sorted by the number of posts in descending order.
If I'm not wrong, you are asking for the users with the highest number of posts created in the last 24 hrs.
To accomplish this, do the following:
$users = User::withCount(['posts' => function ($query) {
$query->where('created_at', '>=', carbon()->now()->subDay());
}])->orderBy('posts_count', 'DESC')
->get();
As the documentation states, you can add constraints to the queries.
Counting Related Models
If you want to count the number of results from a relationship without actually loading them you may use the
withCount method, which will place a {relation}_count column on
your resulting models. For example:
$posts = App\Post::withCount('comments')->get();
foreach ($posts as $post) {
echo $post->comments_count;
}
You may add the "counts" for multiple relations as well as add
constraints to the queries:
$posts = Post::withCount(['votes', 'comments' => function ($query) {
$query->where('content', 'like', 'foo%');
}])->get();
echo $posts[0]->votes_count;
echo $posts[0]->comments_count;
use Carbon\Carbon;
get user id:
$minusday = Carbon::now()->subDay();
$user_id = DB::table('posts')
->select('user_id', DB::raw('count(id) as total'))
->where('created_at', '>=', $minusday)
->groupBy('user_id')
->orderBy('total','desc')
->limit(1)
->get();
In regular SQL syntax you'd need something like below:
SELECT COUNT(id), user_id
FROM posts
WHERE created_at = today
GROUP BY user_id
ORDER BY COUNT(user_id) DESC
LIMIT 1;
It gets all the posts, groups them by user_id, sorts them with the highest user_id count up top and gets the first record.
I am by no means an expert on SQL, let alone the query builder in Laravel, so someone else would probably be better at writing that.
I know that you can get the posts that were created today by using Carbon, like so:
Post::whereDate('created_at', Carbon::today())->get();
EDIT: This might work for you:
$last24h = Carbon::now()->subDay();
DB::table('posts')
->select(array(DB::raw('COUNT(id)', 'user_id')))
->where('created_at', '>=', $last24h)
->groupBy('user_id')
->orderBy('COUNT(id)', 'DESC')
->limit(1)
->get();
Be sure to include use Carbon\Carbon to be able to use Carbon.
This should give you both the amount of posts and the corresponding user id.

How to fetch latest posts and specific post id at first in laravel eloquent

Is there way to fetch latest posts with pagination And I also want a specific post to first position in returned collection.
I tried this...
Post::where(function ($query) {
$query->where('status', 'draft')->orWhere('status', 'published');
})
->orWhere('id', 21)
->with(['author.profile'])
->orderBy('created_at', 'desc')
->paginate(3);
In this query I do get the 21 post id but it is on 3rd page. I want to get it on first place. Please guide How can I do this.
Thanks
You can achieve this by using a raw statement in your orderBy
Post::orderBy(DB::raw('id = 5'), 'DESC')
->orderBy('created_at', 'desc')
This is because mysql can use boolean expressions in order by statements
By using eloquent you do like this
Post::where('id', '=', 21)->orderBy('created_at','desc')->first();

Paginate based on conditional with relationship

I'm trying to paginate based on a conditional on a relationship. Thought this would work but it does not..
Product::with(['manufacturer' => function($query){
$query->where('name', '=', 'Maker');
}])->paginate(10)->toArray();
for some reason It only works on the first model. I can tell because its the only one loading the manufacturer data.
Anyone have any idea how to do this?
thanks!
Laravel offers convenient way to query relationships (docs)
I think, this is what you want
$products = Product::whereHas('manufacturer', function($q)
{
$q->where('name', '=', 'Maker');
})->get();
You may add pagination and other things as you wish.

Resources