Order and Sub Order collection - laravel 7 (Simple) - php

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();

Related

Laravel - How to sort an array of objects in ascending order by ID

I need to sort an array of objects in ascending order by ID called $messages, I tried many things but none seem to be working. Here is what I tried:
public function getMessagesPage(Request $request)
{
$user_id = $request->session()->get('id');
$user_second = User::where('username', $request->username)->first();
$messages_1 = Messages::where('user_1', $user_id, 'AND')->where('user_2', $user_second->id)->orderBy('id', 'asc')->get();
$messages_2 = Messages::where('user_2', $user_id, 'AND')->where('user_1', $user_second->id)->orderBy('id', 'asc')->get();
$messages = $messages_1->merge($messages_2);
$messages = collect($messages);
$messages->sortBy('id');
return view('messages')->with('messages', $messages)->with('user_id', $user_id)->with('user_second', $user_second);
}
You can sort your collection with sortBy() but remember that the function returns the collection sorted, doesn't mutate the original collection, so you have to change this line:
//$messages->sortBy('id');
$messages = $messages->sortBy('id');
As better alternative you can get all the messages sorted with only one query:
$messages = Messages::where([['user_1', $user_id], ['user_2', $user_second->id]])
->orWhere([['user_2', $user_id], ['user_1', $user_second->id]])
->orderBy('id', 'asc')
->get()
This is the same as writing this SQL:
select * from messages
where (user_1 = $user_id and user_2 = $user_second->id)
or (user_2 = $user_id and user_1 = $user_second->id)
order by id asc
You could try
$messages_1 = Messages::where('user_1', $user_id)->where('user_2', $user_second->id)->orderBy('id', 'asc')->get();
$messages_2 = Messages::where('user_2', $user_id)->where('user_1', $user_second->id)->orderBy('id', 'asc')->get();
Remove the AND from the first WHERE. Eloquent knows that if you chain ->where() clauses, to use AND between them.
Alternatively, if you are using Laravel 5.3 or greater you can pass an array to in a where clause
$messages_1 = Messages::where([
'user_1' => $user_id,
'user_2' => $user_second->id])
->orderBy('id', 'asc')
->get();
Alternatively, if the following $messages = collect($messages); is correctly returning a Key / Value pair array, you should simply be able to use the following
return view('messages')
->with([
'messages' => sort($messages),
'user_id' => $user_id,
'user_second' => $user_second
]);

Count from other table

I am having problem to count number of devices where guid is not null.
It need to get all the shops by user user_id and then count all the devices where guid is not null.
$shops = Shop::with('devices')->where('user_id', $userId)->get();
$deviceActive = $shops->reduce(function ($carry, $item) {
return $carry + $item->devices->whereNotNull('guid')->count();
});
dd($deviceActive );
It work when I do:
return $carry + $item->devices->count();
but it need to count where guid is not null.
I would also be interested to hear if there is alternative reduce approach.
Since $item->devices is a collection there is no whereNotNull() for collections. So try to use where():
$item->devices->where('guid', '<>', null)->count();
Try:
$shops = Shop::with('devices')
->where('user_id', $userId)
->where('guid', '!=', null)->get();
$get_count = count($shops); // it return how many values have $shops
OR
$shops= DB::table('devices')->where('user_id', $userId)
->where('guid', '!=', null)->get();
$get_count = count($shops);
if you did not have the class DB add at your controller:
use DB;

Can I do Model->where('id', ARRAY) multiple where conditions?

The title says it all.
I get that I can do this :
DB::table('items')->where('something', 'value')->get()
But what I want to check the where condition for multiple values like so:
DB::table('items')->where('something', 'array_of_value')->get()
Is there an easy way of doing this?
There's whereIn():
$items = DB::table('items')->whereIn('id', [1, 2, 3])->get();
You could use one of the below solutions:
$items = Item::whereIn('id', [1,2,..])->get();
or:
$items = DB::table('items')->whereIn('id',[1,2,..])->get();
If you need by several params:
$ids = [1,2,3,4];
$not_ids = [5,6,7,8];
DB::table('table')->whereIn('id', $ids)
->whereNotIn('id', $not_ids)
->where('status', 1)
->get();
You can use whereIn which accepts an array as second paramter.
DB:table('table')
->whereIn('column', [value, value, value])
->get()
You can chain where multiple times.
DB:table('table')->where('column', 'operator', 'value')
->where('column', 'operator', 'value')
->where('column', 'operator', 'value')
->get();
This will use AND operator. if you need OR you can use orWhere method.
For advanced where statements
DB::table('table')
->where('column', 'operator', 'value')
->orWhere(function($query)
{
$query->where('column', 'operator', 'value')
->where('column', 'operator', 'value');
})
->get();
If you are searching by ID you can also use:
$items = Item::find(array_of_ids);
It's work for me
fetch just id then search in array
$shops = Shop::Where('user_id', Auth::id())->get('id');
$categories = Category::whereIn('shop_id',$shops)->paginate(7);
$whereData = [['name', 'test'], ['id', '<>', '5']];
$users = DB::table('users')->where($whereData)->get();
WHERE AND SELECT Condition In Array Format Laravel
use DB;
$conditions = array(
array('email', '=', 'user#gmail.com')
);
$selected = array('id','name','email','mobile','created');
$result = DB::table('users')->select($selected)->where($conditions)->get();

getting database results from an array of ids [duplicate]

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 :)

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