I have an order_status_transaction table which is a log table for recording the status of transactions
I am trying to write an eloquent builder to get all of the transactions with a CURRENT status of 5 for example.
This is the closest I have got
$transactions = $this->whereHas('statuses', function ($query) use ($statusId) {
$query->where('order_status_transaction.order_status_id', $statusId)->where();
});
But it does not check if it is the most recent. I don't want to get the collection and filter the collection, can this be going purely in a builder?
This should do
$transactions = OrderStatusTransaction::where('order_status_id', $statusId)->latest()->get();
Assuming OrderStatusTransaction as your model name.
As in the comments, latest sorts by latest.
Query builder has a method called latest() and so you would write something like this:
OrderStatusTransaction::where('order_status_id', $statusId)
->latest()
->get();
This will get all the records with the given status id going from most recent first to oldest.
You can read me about this here:
https://laravel.com/docs/5.7/queries#ordering-grouping-limit-and-offset
Related
I want to group by an laravel eloquent with two classes come in with() I want to add column of these two with classes in group by
$query = CourseEnrolled::with('user', 'course')->latest()->groupBy('course_id','user_id')
Here course id come from course table and user id come from user table. it successfully group columns but does sort latest record. It display old record only
I have also tried but still same result
$query = CourseEnrolled::with('user', 'course')->orderBy('created_at')->groupBy('course_id','user_id')
u cant query them directly with the eloquent model of CourseEnrolled. if you want to add additional queries with other models, you have to use with() in this way :
CourseEnrolled::with('user' , function($user){
// now u can use any query with user fields
$user->where('user-name' , 'value');
})
This query solve my problem
$query = CourseEnrolled::with('user', 'course')->latest()->whereIn('id', function($q){
$q->select(DB::raw('MAX(id) FROM course_enrolleds GROUP BY user_id,course_id'));
});
I need to get the latest activity from the database and order them by created_at.
There is a database table of orders, which has a shop_id, and there is a database table of collected_birthdays, which also has a shop_id incommon.
How to get the latest orders and collected_birthdays which has the same shop_id and take 5 latest records?
The mission is to display to the user the latest records of the two database tables, in the future, there will be more tables which will I need to display and get the latest 5 records.
Currently I found it make it work this way:
$shop = Shop::FindOrFail(1);
$orders = $shop->orders()->orderBy('created_at', 'DESC')->limit(5)->get();
$collectedBirthdays = $shop->collectedBirthdays()->orderBy('created_at', 'DESC')->limit(5)->get();
$latestActivity = $orders->merge($collectedBirthdays)->sortByDesc('created_at')->take(5);
This is not the best solution, but made it work.
You can use DB::raw(). It will take the raw query and give you the reault.
$data = DB::raw(
'Select o.shop_id, o.created_at, cb.shop_id, cb.created_at
From orders as o
Inner Join collected_birthdays as cb on cb.shop_id = o.shop_id
Order By o.created_at DESC -- or use cb.created_at
Limit 5;'
)->get();
You can use take function in eloquent and do something like this:
Shop::join('orders', 'orders.shop_id', '=', 'shops.id')->orderBy('orders.created_at', 'DESC')->take(5)->get()
Or if you want to stop using join(table, onCondition..) I recommend you use Eloquent Power Joins package which will automatically generate joins for you based on relationship declared inside your model and use it like this:
Shop::joinRelationship('orders')->orderBy('orders.created_at', 'DESC')->take(5)->get();
Link to package: https://github.com/kirschbaum-development/eloquent-power-joins
This would also be possible by using paginate()
I would like to paginate my results I get from my relationship. I have a products table/controller, a users table/controller and a markedProducts table. However, I don't have a markedProducts table because I don't actually need it. I use this solution to get all marked products of one user in my user model:
public function markedProducts(){
return $this->belongsToMany('App\Product', 'products_marks');
}
My question now is how can I paginate my results and my second question is how can I get the created_at value of each row in my markedProducts table?
Because my solution is only returning the marked products. However, I would like to show the user when he has marked the product.
So far I had this idea:
$markedProducts = DB::table('products_marks')->where('user_id', Auth::id())->orderBy('created_at', 'desc')->paginate(2);
$products = Product::whereIn('id', $markedProducts->lists('product_id'));
However, ->lists() is not a method anymore and I actually don't want to bypass the Laravel methods and I don't want to loop through my pagination to get an array with all product_id's.
Do you guys have any good and performant solution?
Kind regards and thank you!
Auth::user() will return the authenticated user.
And use relationship method markedProducts() to get the query of products.
And then orderBy the column created_at of pivot table.
At last, apply paginate to this eloquent builder.
Auth::user()->markedProducts()->orderBy('products_marks.created_at', 'DESC')->paginate($limit);
How to use searcable() method on results returned by query builder? Suppose there are five tables:
products
vendors
categories
vendor_products (pivot table for Products and Vendors)
product_categories (pivot table for Products and Categories)
Is there a way to use searchable on the following query:
return \DB::table("products")
->join('vendor_products', function ($join) {
$join->on('products.id', '=', 'vendor_products.product_id')
->MANY_OTHER_WHERE_CONDITIONS
})
->join('categories', function ($join) {
$join->on('category_id', '=', 'categories.id');
})
->MANY_OTHER_CONDITIONS
->searchable()
But Laravel Scout return error:
Call to undefined method Illuminate\Database\Query\Builder::searchable()
Is there a way to upload the results of above query?
I have added searcable trait on vendors, categories, and products models.
It looks like Scout only work when we have Eloquent relationship returned from the query and don't work on query builder.
Acording to Laravel Documentation
Laravel Scout provides a simple, driver based solution for adding full-text search to your Eloquent models.
Query builder doesn't have this functionality.
Instead, a non so fancy solution you could implement is to compare every column using WHERE LIKE. This supposes a more slowly functionality than Laravel Scope but can do the trick if you dont want to use Eloquent.
My Recomendation is to use Eloquent. Is a faster and easier way to work with databases while using laravel
Problem resolved, all credit goes to #kfirba. Copying his response from his blog
The searchable() method is only available for Eloquent’s query builder. Try converting your query above to use Eloquent. Change the DB::table(‘products’)->join... to Products::join...
You may need to change the “toSearchableArray()” method implementation to include your new fields that are not part of the Product model (vendor_quantity, vendor_price, etc.)
Here, is my eloquent
$contacts = Contact::where('property_id',$commercial->id)->where('property_type','commercial_lease')
->with('contact_log')
->with('user_name')
->with('contact_log.contact_log_name')
->get();
->with('contact_log')
with this relationship...I got each and every data from that table using ->with('contact_log'). But i want last inserted data via with relationship.
Others will remains same. But need to get only last data via this relation.
You need to apply extra constraints on your contact_log relation in order to fetch only the last entry.
Replace
->with('contact_log')
with
->with('contact_log', function($query) {
// order latest entries first
$query->orderBy('created_at', 'DESC');
// take only the first entry
$query->take(1);
})