Laravel Eloquent - take results randomly from whereIn - php

Laravel version 4.2
I'm having issues with this one problem I have.
I need to fill a quota of 5 results however I only have an array size of 3. I also need the rows to be selected randomly from the Array.
*edit: Fetching all results is not feasible
$store_id_array = array('111', '222' , '333');
$reviews = Review::whereIn('store_id', $store_id_array)
->take(5)
->get();
return Response::json($reviews);
This will return 5 results however only from the first item in the array.
How do I select randomly from the array items?

For Laravel below version 5:
orderBy(DB::raw('RAND()')) like this:
$reviews = Review::whereIn('store_id', $store_id_array)
->orderBy(DB::raw('RAND()'))
->take(5)
->get();
For Laravel 5.0 +
use inRandomOrder() method:
$reviews = Review::whereIn('store_id', $store_id_array)
->inRandomOrder()
->take(5)
->get();

public function index()
{
$categories = Category::latest()->get();
$protfolios = Protfolio::all();
$randompost = Post::approved()->publish()->take(4)->InRandomOrder()->get();
$allposts = Post::where('price', 0)->approved()->publish()->take(8)->get();
$posts = Post::latest()->where('price', '>=', 0)->approved()->publish()->take(8)->get();
$latestposts = Post::latest()->approved()->publish()->take(8)->get();
return view('welcome',compact('posts','randompost ','categories','allposts','latestposts','protfolios'));
}

Related

Order and Sub Order collection - laravel 7 (Simple)

lets say I have a collection of users Users::all()
I would like to take sort/order it like such Users::all()->sort('created_at', 'DESC')
then I would like to sub order it by an array like [1,5,3,9,4,8] so perhpas a call like this Users::all()->sort('created_at', 'DESC')->sortBy("id", [1,5,3,9,4,8])
Any Advice?
Edit 1
I have found this, is this correct to use?
$ids = collect([1,5,3,9,4,8]);
$users = Users::all()->sort('created_at', 'DESC');
$users = $ids->map(function($id) use($users) {
return $users->where('cat_id', $id)->first();
});
I think you could just invoke orderBy() twice.
$ids = [1,5,3,9,4,8];
$users = Users::all()
->orderBy('created_at', 'desc')
->orderBy($ids)
->get();
Does this answer your question?
You can use whereIn like this probably:
$ids = [1,5,3,9,4,8];
$users = Users::all()
->orderBy('created_at', 'desc')
->whereIn('cat_id', $ids)
->get();
https://laravel.com/docs/9.x/queries#additional-where-clauses
The whereIn method verifies that a given column's value is contained within the given array
So I found a solution.
$ids = json_decode($interview->question_ids ?? '[]');
if(count($ids) == 0){ // if empty create new id array and save to DB
$ids = collect(questions::all()->where('interview_id', $interview->id)->pluck('id')->toArray());
$interview->question_ids = json_encode($ids);
$interview->save();
}
$questions = questions::all()->where('interview_id', $interview->id)->sortBy([
['order_timestamp', 'asc'],
['created_at', 'asc'],
]);
$questions = $ids->map(function($id) use($questions) {
return $questions->where('id', $id)->first();
});
$questions = $questions->flatten();

Laravel 5.4 Eloquent get x random records from collection where property is null

Learning eloquent/laravel. I have a collection:
$regions = Region::with('neighbors')
->join('cards', 'cards.id', '=', 'regions.risk_card_id')
->get();
I have a value or rows:
$regionsPerUser = 8;
I am doing this to pull random records:
$regions = $regions->random($regionsPerUser);
But I need to filter this selection where $regions->user_id is not null.
Is there a way to filter the random call as part of chaining?
I tried this which does not work:
$regions = $regions->whereNotNull('user_id')->random($regionsPerUser);
And I am wondering if there is a way to neatly do this in one chained statement as opposed to going down the path of filter / map.
Why not just add your conditions to a sql-query:
$regions = Region::with('neighbors')
->join('cards', 'cards.id', '=', 'regions.risk_card_id')
->whereNotNull('user_id')
->inRandomOrder()
->limit($regionsPerUser)
->get();
If you already have a collection then you can do something like:
$regions = $regions
->filter(function ($value) {
return !is_null($value['user_id']);
})
->random($regionsPerUser);

eloquent laravel: How to get a row count from a ->get()

I'm having a lot of trouble figuring out how to use this collection to count rows.
$wordlist = \DB::table('wordlist')->where('id', '<=', $correctedComparisons)
->get();
I have tried adding->count() but didn't work. I have tried doing count($wordlist). I'm not really sure what to do without needing a second request as a->count() method.
Answer has been updated
count is a Collection method. The query builder returns an array. So in order to get the count, you would just count it like you normally would with an array:
$wordCount = count($wordlist);
If you have a wordlist model, then you can use Eloquent to get a Collection and then use the Collection's count method. Example:
$wordlist = Wordlist::where('id', '<=', $correctedComparisons)->get();
$wordCount = $wordlist->count();
There is/was a discussion on having the query builder return a collection here: https://github.com/laravel/framework/issues/10478
However as of now, the query builder always returns an array.
Edit: As linked above, the query builder now returns a collection (not an array). As a result, what JP Foster was trying to do initially will work:
$wordlist = \DB::table('wordlist')->where('id', '<=', $correctedComparisons)
->get();
$wordCount = $wordlist->count();
However, as indicated by Leon in the comments, if all you want is the count, then querying for it directly is much faster than fetching an entire collection and then getting the count. In other words, you can do this:
// Query builder
$wordCount = \DB::table('wordlist')->where('id', '<=', $correctedComparisons)
->count();
// Eloquent
$wordCount = Wordlist::where('id', '<=', $correctedComparisons)->count();
Direct get a count of row
Using Eloquent
//Useing Eloquent
$count = Model::count();
//example
$count1 = Wordlist::count();
Using query builder
//Using query builder
$count = \DB::table('table_name')->count();
//example
$count2 = \DB::table('wordlist')->where('id', '<=', $correctedComparisons)->count();
Its better to access the count with the laravels count method
$count = Model::where('status','=','1')->count();
or
$count = Model::count();
also, you can fetch all data and count in the blade file.
for example:
your code in the controller
$posts = Post::all();
return view('post', compact('posts'));
your code in the blade file.
{{ $posts->count() }}
finally, you can see the total of your posts.
//controller $count = Post::count(); return view('post', compact('count'));
//blade {{$count}}
or
//controller $posts = Post::all(); return view('post', compact('posts'));
//blade{{count($posts)}}

Laravel: For each where clause

I'm trying to return a query that has an arbitrary amount of where clauses based on the number of tags a user submits.
//unknown number of ids to query on
$tag_ids = array(1,5);
//multiple joins with closure
$items = DB::table('archives_items_metadata')->join('tags', 'archives_items_metadata.tag_id', '=', 'tags.id')->join('archives_items', 'archives_items_metadata.archive_item_id', '=', 'archives_items.id')->join('items', 'archives_items.item_id', '=', 'items.id')
->where(function ($query) use ($tag_ids) {
foreach ($tag_ids as $tag_id)
{
$query->where('archives_items_metadata.tag_id', $tag_id);
}
})->get();
The result I get is an empty array even though when I try array(1) or array(5) by themselves, they both return the same item. What am I missing?
EDIT::
I'm looking to return items that have each of the tag ids specified. The reference of items to tags is stored on the archives_items_metadata table. How can I get the result I'm expecting, and what's the most efficient way to accomplish this?
You are looking to do a WHERE tag_id IN (1, 2, 3) style clause laravel has the whereIn($col, $vals) builder function.
->whereIn('archives_items_metadata.tag_id', $tag_ids)
search for "whereIn" in the official docs
$tag_count = count($tag_ids);
$items = DB::table('archives_items')->join('archives_items_metadata', 'archives_items_metadata.archive_item_id', '=', 'archives_items.id')->join('tags', 'archives_items_metadata.tag_id', '=', 'tags.id')
->whereIn('archives_items_metadata.tag_id', $tag_ids)->whereNull('archives_items_metadata.deleted_at')
->groupBy('archives_items_metadata.archive_item_id')->havingRaw('count(*)='.$tag_count->get();

Search and sort in laravel?

In laravel, I know you can do
$users = Post::where('hide', '=', 0)->take(40)->get();
to get all Post-objects where hide = 0 and
$users = Post::orderBy('created_at', 'DESC')->take(20)->get();
to sort them, but what if I want to do both?
You should be able to do
$users = Post::where('hide', '=', 0)->orderBy('created_at', 'desc')->take(20)->get();
You can continue to chain methods from the query builder after the where.

Categories