I have some search with multiple arguments and I want to query if the input is not null then make query argument.
I tried many ways but I cannot get query results.
Here is my sample code
$products = Product::where('game_id',$tg->id);
if($keyword !=null){
$products->where("name","like",$keyword);
}
if($price_start !=null){
$products->where("price",">",$price_start);
}
if($price_end !=null){
$products->where("price","<",$price_end);
}
if($avalibility !=null){
$products->where("status","=",$avalibility);
}
$products->orderBy("created_at","DESC");
$products->get();
Try this
$products = Product::select('*')
->where(function ($query) use($request){
if($keyword !=null){
$query->where('name','like','%'.$keyword.'%');
}
if($price_start !=null){
$query->where("price",">",$price_start);
}
if($price_end !=null){
$query->where("price","<",$price_end);
}
if($avalibility !=null){
$query->where("status","=",$avalibility);
}
})
->where('game_id',$tg->id)
->orderBy('created_at', 'DESC')
->get();
In your code assign the result of query to the variable products as follows:
$products = $products->get();
now the $products will contain the result
Try adding ->get() to the query builder.
$products = Product::where('game_id',$tg->id)->orderBy->('created_at', 'desc')->get().
Use the explicit ->get() on the query builder to get a collection. And then use laravels collection
methods (https://laravel.com/docs/5.8/collections#available-methods) to add further where clauses and sort the results (see sortBy method) or add the orderBy clause to the intial query (as above). You can leave out the final ->get() since it's called on the query builder.
Using the 'where' collection method inside the if statement:
if(isset($keyword)) {
$products = $products->where('name','like', '%' . $keyword . '%');
}
First you need to validate your data as follow
$request->validate([
'id' => 'required',
'keyword' => 'required',
'price_start' => 'required',
'availability' => 'required'
]);
Now you can perform your data query with these validate Data. If you have multiple data for where method you might be put all of them in array ,after that to fetch the data-you should use get() method; like as bellow
$products = Product::where([
['id', '=', $request->id],
['keyword', 'like', $request->keyword]
])
->orderBy("created_at","DESC")
->get();
Related
Having a hard time understanding how to order my Laravel model by a nested relationship.
Here are the Models.
User.php
// Has many small_groups through a pivot table
public function small_groups()
{
return $this->belongsToMany('App\Models\SmallGroup')->withPivot('type')->withTimestamps();
}
SmallGroup.php
// Has many SmallGroupLessons
public function small_group_lessons()
{
return $this->hasMany('App\Models\SmallGroupLesson');
}
SmallGroupLessons.php
// Has many SmallGroupLessonComments
public function small_group_lesson_comments()
{
return $this->hasMany('App\Models\SmallGroupLessonComment');
}
SmallGroupLessonsComment.php
// Belongs to SmallGroupLesson
public function small_group_lesson()
{
return $this->belongsTo('App\Models\SmallGroupLesson');
}
What's I'm trying to do, is pull all of the user's small groups, ordered by the most recent SmallGroupLessonComment if one exists. I've been doing some research, and it sounds like using Laravels ORM in this use case will not work. However, I'm not entirely sure on how to create the join on the nested relationship.
I tried the following, but this only pulls in the most latest SmallGroupLessonComment, however, it does not order the entire result set.
$small_groups = $user->small_groups()->with([
'small_group_lessons' => function($q) {
$q->with([
'latest_comment' => function($q) {
$q->orderBy('created_at', 'asc');
}
]);
}
])->paginate($limit);
Update
Was able to solve it via the following...
$small_groups = $user->small_groups()->with([
'small_group_lessons' => function($q) {
$q->with([
'latest_comment' => function($q) {
$q->orderBy('created_at', 'asc');
}
]);
}
])
->leftJoin('small_group_lessons', 'small_group_lessons.small_group_id', '=', 'small_groups.id')
->leftJoin('small_group_lesson_comments', 'small_group_lesson_comments.small_group_lesson_id', '=', 'small_group_lessons.id')
->orderBy('small_group_lesson_comments.created_at', 'desc')
->paginate($limit);
Update #2
The above doesn't work. I get multiple small groups back that are the same item.
Update #3
This query is pretty close, but it's just ordered by the most recent SmallGroupLesson. Ideally, we order by the SmallGroupLessonComment 🤔
$small_groups = $user->small_groups()->with(
[
'small_group_lessons' => function($q) {
$q->with('latest_comment');
$q->orderBy('created_at', 'desc');
}
],
)
->orderBy(
SmallGroupLesson::select('created_at')
->whereColumn('small_group_id', 'small_groups.id')
->orderBy(SmallGroupLessonComment::select('created_at')
->whereColumn('small_group_lesson_id', 'small_group_lessons.id')
->orderBy('created_at', 'desc')
->limit(1), 'desc')
->limit(1), 'desc'
)
->paginate();
$data=User::select('*')->leftJoin('small_group_lessons','small_group_lessons.user_id','user.id')
->ordeBy('small_group_lessons.created_at','DESC')->get();
try like this
I was able to solve it via the following. Ordering based off the latest comment now works correctly.
$small_groups = $user->small_groups()->with([
'small_group_lessons' => function($q) {
$q->with('latest_comment');
$q->orderBy('created_at', 'desc');
}],
)
->orderBy(
SmallGroupLesson::select('small_group_lesson_comments.created_at')
->join('small_group_lesson_comments', 'small_group_lessons.id', '=', 'small_group_lesson_comments.small_group_lesson_id')
->whereColumn('small_group_id', 'small_groups.id')
->latest()
->limit(1), 'desc'
)
->paginate();
I am not able to find any perfect solution for it.
Controller:
$servicerequest = ServiceRequest::selectRaw('count(id) as totalservice,max(created_date) as last_service,service_provider_id,id,service_id,account_id,service_request,created_date')->with(['account' => function($first) use ($keyword) {
$first->select('id', 'restaurant_name')->orderBy('restaurant_name', 'DESC');
}])
->with(['serviceProvider' => function($query) use ($keyword) {
$query->select('id', 'company_name');
}])->groupBy('account_id')
->orderBy('company_name', 'DESC')
->paginate(100);
I need an order by on model relation table field and that effect on main table data. because it's and one to one relationship so no need to order by on the inside.
Like I need to the orderby whole on relations data.
Collection:
You must make join your relation table to used orderBy relation table.
You can try this code.
$servicerequest = ServiceRequest::selectRaw('count(id) as totalservice, max(created_date) as last_service,service_provider_id,id,service_id,account_id,service_request,created_date, SERVICEPROVIDERTABLE.company_name')
->join('serviceProvider', 'SERVICEPROVIDERTABLE.id', '=', 'SERVICEREQUESTTABLE.service_provider_id')
->with([
'account' => function ($first) use ($keyword) {
$first->select('id', 'restaurant_name')
->orderBy('restaurant_name', 'DESC');
}
])
//->with([
// 'serviceProvider' => function ($query) use ($keyword) {
// $query->select('id', 'company_name');
// }
//])
->groupBy('account_id')
->orderBy('SERVICEPROVIDERTABLE.company_name', 'DESC')
->paginate(100);
i hope this works.
I am trying to use Laravel and eloquent to return results based on the following query.
$blogPosts = BlogPosts::with('blog_user', 'blog_categories', 'blog_comments', 'tags')
->orderBy('created_at', 'desc')
->paginate(5);
Ok, so that is fine, it return exactly what it should, all the blog posts with associated relations to other tables.
What I now want to do is return only the $blogPosts where a tag is clicked by the user. So let's say there is a tag "PHP", so I pass in that value as $tag to the method. I then have something like this.
public function tag_search($tag)
{
$blogPosts = BlogPosts::with('blog_user', 'blog_categories', 'blog_comments', 'tags')
->where('tags', $tag)
->orderBy('created_at', 'desc')
->paginate(5);
$categories = BlogCategories::with('blog_posts')->get();
$data = array('blogPosts' => $blogPosts, 'categories' => $categories,
);
return view('blog.index')->with($data);
}
Now my issue is actually relatively simple I guess, if the where clause was a column in the BlogPosts table it would work, I know this because I tried that.
However the above won't work as is, I can only use;
->where('x', y)
Where x is a field in the BlogPosts table. I want to return a set of values where the submitted $tag is the same as one associated to the tags attached to the blog posts.
Make sense? I think I am over thinking it the point I am just not thinking now :)
Add the column field 'tags' to your table and then these queries:
$blogPosts = BlogPosts::with('blog_user', 'blog_categories', 'blog_comments', 'tags')
->where('tags', '=', $tag)
->orderBy('created_at', 'desc')
->paginate(5);
$categories = BlogCategories::with('blog_posts')->get();
return view('blog.index', compact ('categories', 'blogposts'));
Ok so the answer was to use whereHas like this.
$blogPosts = BlogPosts::whereHas('tags', function ($query) use ($tag) {
$query->where('name', $tag);
})->orderBy('created_at', 'desc')
->paginate(5);
That returns a search based on the associated elements.
I'm using Laravel 4 and Eloquent ORM. I'm currently pulling records from my database using the following code:
public function index($type, $id)
{
$asset = Asset::where('public_id', '=', $id)
->with('attachments')
->with('attachments.attachment')
->with('tracks')
->with('tracks.track')
->where('locale', '=', Config::get('app.locale'))
->first();
return View::make('view-asset.index')
->with('asset', $asset)
->with('type', $type);
}
The table joined to this query using the with('tracks') statement has a column in it called track_order - I would like to be able to sort the rows returned by this part of the query by that column so that the tracks stored in the database are returned in the correct order.
Is it possible to do this and if so, how should I do it? So far I've tried something like this:
public function index($type, $id)
{
$asset = Asset::where('public_id', '=', $id)
->with('attachments')
->with('attachments.attachment')
->with('tracks')
->with('tracks.track')
->where('locale', '=', Config::get('app.locale'))
->orderBy('tracks.track_order', 'ASC')
->first();
return View::make('view-asset.index')
->with('asset', $asset)
->with('type', $type);
}
Which doesn't work and I can't figure out a way of doing this other than splitting things up into multiple queries.
You most certainly can:
with(['tracks' => function($query)
{
$query->orderBy('track_order', 'asc');
}])
Refer to Eager Loading Contraints in the documentation for more.
I have a query builder that works:
$article = Page::where('slug', '=', $slug)
->where('hide', '=', $hidden)
->first();
But I want to only add the second where statement if hidden is equal to 1. I've tried the code below which shows the logic of what I'm trying to do, but it doesn't work.
$article = Page::where('slug', '=', $slug);
if ($hidden == 1) {
$article->where('hide', '=', 1);
}
$article->first();
I'm using Laravel 4, but I think the question still stands with Laravel 3.
Yeah there's a little "gotcha" with Eloquent and the query builder. Try the code below ;)
$query = Page::where('slug', '=', $slug);
if ($hidden == 1) {
$query = $query->where('hide', '=', 1);
}
$article = $query->first();
Note the assigning of $query within the conditional. This is becuase the first where (statically called) returns a different object to the query object within the conditional. One way to get around this, I believe due to a recent commit, is like so:
$query = Page::where('slug', '=', $slug)->query();
This will return the query object and you can do what you want as per normal (Instead of re-assigning $query).
Hope that helps.