I'm experiencing difficulty in writing this query in laravel 5.1,
select * from `host_requests` where `host_id` = 5 and (`email` LIKE "%v%" or `request_url` LIKE "%v%")
The purpose of this query is to fetch records that are associated with host_id = 5, also email and request_url are optional if they set then LIKE clause should be used.
I wrote the query in laravel like this
$searchname = "v";
$hostid = "5";
$data = HostRequest::where('email', 'LIKE', '%' . $searchname . '%')
->where('host_id', $hostid)
->orwhere('request_url', 'LIKE', '%' . $searchname . '%')
->latest('id')
->paginate($size);
It is fetching all the records that are also not associated with host_id = 5.
Any help is much appreciated..Thanks
You should use where() with closure like this:
$data = HostRequest::where('host_id', $hostid)
->where(function($q) use($searchname) {
$q->where('email', 'like', '%'.$searchname.'%')
->orWhere('request_url', 'like', '%'.$searchname.'%');
})->orderBy('id', 'desc')
->paginate($size);
Try this code:
$data = HostRequest::where(function ($query) use ($searchname) {
$query->orwhere('email', 'like', '%'.$searchname.'%')
->orWhere('request_url', 'like', '%'.$searchname.'%');
})
->where('host_id', $hostid)
->latest('host_id')
->paginate($size);
Related
I'm using SoftDeletesin my projects, which is recognized as deleted_at in database table, I want to search and find only deleted rows.
Here is my controller code
public function trashedJobSearch(Request $request)
{
$search = $request->get('search');
$jobs = Jobs::select('id', 'company_name', 'position_name', 'job_description','deleted_at', 'created_at', 'expire_date', 'status')
->where(DB::raw('lower(company_name)'), 'like', '%' . mb_strtolower($search) . '%')
->orWhere(DB::raw('lower(position_name)'), 'like', '%' . mb_strtolower($search) . '%')
->where('deleted_at', '!=', null)
->paginate(10);
return view('/trashed', compact('jobs'));
}
I tried to use onlyTrashed() but it's not working either.
As you have orWhere you need to use a grouping and also onlyTrashed
Jobs::select('id', 'company_name', 'position_name', 'job_description','deleted_at', 'created_at', 'expire_date', 'status')
->where(function ($query) use ($search) {
$query->where(DB::raw('lower(company_name)'), 'like', '%' . mb_strtolower($search) . '%')
->orWhere(DB::raw('lower(position_name)'), 'like', '%' . mb_strtolower($search) . '%');
})->onlyTrashed()
->paginate(10);
The onlyTrashed() method should work for you. Docs for Laravel deleted entries. I have seen times where adding the raw select statement screws it up though.
Take out the extra bits with the select and DB::raw and then add them in after you have what you need. Start with the simplest:
$testOfDeletedOnlyJobs = Jobs::onlyTrashed()->get();
From here, add in the other parts of your query to see where and why it fails. If the above gives you nothing, perhaps there are no deleted records?
You can use
Model::onlyTrashed()->get();
Did you have looking for this post yet?
How to get all rows (soft deleted too) from a table in Laravel?
You can try this.
In your Model-
use Illuminate\Database\Eloquent\SoftDeletes;
class ModelName extends Model
{
use SoftDeletes;
}
To get only deleted rows
$search = $request->get('search');
$data = App\ModelName::onlyTrashed()
->where('id', $search)
->get();
I have a query like so
$data = City::with('hotel')->orwherehas('hotel', function ($query) use ($user_input) {
//here i want to limit this result to 5
$query->where('name', 'LIKE', '%' . $user_input . '%')->take(5);
// $query->take(5); i have tried this too
})->orWhere('name', 'LIKE', '%' . $user_input . '%')->get();
inside the whereHas clause, I have a query that I want to limit to 5, now I tried limit, take but no luck after that where nothing is working I don't know why
You can pass your query to the ->with() query builder method:
$data = City::with(['hotel' => function($query) use ($user_input) {
$query->where('name', 'LIKE', '%' . $user_input . '%')->limit(5);
}])
->where('name', 'LIKE', '%' . $user_input . '%')
->get();
This will get all hotels associated with a city which have the user input, where the city contains the user input.
Note that the ->orWhere() is not used here.
I've a customer and customer group table. I want to search the customers based on term/filter text.
Say, there is two customer_group_id, 7 and 8. When 8, I'll need to find mobile fields in orWhere clause, otherwise not.
What I've tried is
$contacts = Contact::where(function ($query) use ($term) {
$query->where('contacts.name', 'like', '%' . $term .'%')
});
// For customer_group_id=8
$contacts->when('customer_group_id=8', function($q) use ($term){
return $q->orWhere('mobile', 'like', '%' . $term .'%');
});
The when() is not working. It showing all the results. I know that I've to pass any boolean value in the when() functions first parameter.
Is there any solution for this problem? Or what is the other way I can get the data's.
The when() method doesn't add an if statement to your query, it is just a way to save you from writing an if statement in your code.
To achieve what you're after you can use nested orWhere() clause:
$contacts = Contact::where('name', 'like', '%' . $term . '%')
->orWhere(function ($query) use($term) {
$query->where('customer_group_id', 8)->where('name', 'like', '%' . $term . '%');
})
->get();
If there is more to your query than what you've put in your question then you can simply wrap the above in another where clause:
$contacts = Contact::where(function ($query) use ($term) {
$query->where('name', 'like', '%' . $term . '%')
->orWhere(function ($query) use ($term) {
$query->where('customer_group_id', 8)->where('name', 'like', '%' . $term . '%');
});
})
->where('some column', 'some value')
->get();
What I'm trying to do is setup a server side configuration for a table data. So I have a model CounterLog that has 3 relationships set [belongsTo] category, location, user. I want a query to filter all CounterLog data including relationships, with offset, limit and orderBy methods set and in the same time retrieve all the filtered rows ignoring offset and limit. Here is what I managed until now and maybe understand better what I want:
$search_query = function($q) use ($search) {
$q->where('name', 'like', '%' . $search . '%');
};
$query = CounterLog::where('created_at', 'like', '%' . $search . '%')
->orWhereHas('category', $search_query)
->orWhereHas('location', $search_query)
->orWhereHas('user', $search_query);
$logs = $query->offset($offset)->limit($limit)->get();
$logs_total = $query->offset(0)->count();
In the last line I'm using $query->offset(0) because for some reason if offset is set to a number $logs_total becomes 0. I'm not sure this is the proper way to do it.. but even like this I have no idea how to use orderBy for ex. category.name.
I know I can always use raw queries in eloquent but I want to know if there is a way to use ORM and relationships. I would really appreciate if you could help me with this..cuz the struggle is real.
Thanks a lot :)
Apparently I haven't got a solution with ORM so I did it with "raw" queries:
$query = $this->db->table('counter_logs')
->leftJoin('categories', 'counter_logs.category_id', '=', 'categories.id')
->leftJoin('locations', 'counter_logs.location_id', '=', 'locations.id')
->leftJoin('users', 'counter_logs.user_id', '=', 'users.id');
->where('counter_logs.created_at', 'like', '%' . $search . '%')
->orWhere('categories.name', 'like', '%' . $search . '%')
->orWhere('locations.name', 'like', '%' . $search . '%')
->orWhere('users.name', 'like', '%' . $search . '%');
->select('counter_logs.id as id', 'categories.name as category', 'locations.name as location', 'users.name as user', 'counter_logs.created_at as date');
$json['total'] = $query->count();
$logs = $query->offset($offset)->limit($limit)->orderBy($sort, $order)->get();
Try to swap statements:
$logs_total = $query->count();
$logs = $query->offset($offset)->limit($limit)->get();
Or clone base query, like this:
$total_count_query = clone $query;
$logs = $query->offset($offset)->limit($limit)->get();
$logs_total = $total_count_query->count();
How can I convert this SQL to Laravel5.5 Eloquent format
select * from 'arm_articles' where ('article_tag' like '%standard%' or 'article_topic' like '%standard%' or 'article_details' like '%standard%' or 'article_type' like '%standard%') and ( ('id' between 287 and 296) and 'article_active' = 1) order by 'id' desc
Please observer the braces in the SQL
This is the one i wrote that returns a different sql when i tested the output using ->toSql
$post= PostModel::where('article_tag','like','%'.$contributor_id.'%')->orWhere('article_topic','like','%'.$contributor_id.'%')->orWhere('article_details','like','%'.$contributor_id.'%')->orWhere('article_type','like','%'.$contributor_id.'%')->whereBetween('id', [$end, $start-1])->where('article_active',1)->orderBy('id', 'desc')->take(10)->get();
Find the SQL output from the query above
select * from 'arm_articles' where 'article_tag' like ? or 'article_topic' like ? or 'article_details' like ? or 'article_type' like ? and 'id' between ? and ? and 'article_active' = ? order by 'id' desc limit 10
This output looks like the needed SQL, but the different is the braces on the SQL. so one coin the Eloquent Query Builder to come out with the braces on the query ?
Use the where() closure for parameter grouping:
PostModel::where(function($q) use($contributor_id) {
$q->where('article_tag', 'like', '%' . $contributor_id . '%')
->orWhere('article_topic', 'like', '%' . $contributor_id . '%')
->orWhere('article_details', 'like', '%' . $contributor_id . '%')
->orWhere('article_type', 'like', '%' . $contributor_id . '%');
})
->whereBetween('id', [$end, $start - 1])
->where('article_active', 1)
->orderBy('id', 'desc')
->take(10)
->get();
Try with this
$post = PostModel::where(function ($query) use ($contributor_id) {
$query->orWhere('article_topic','like','%'.$contributor_id.'%')
->orWhere('article_details','like','%'.$contributor_id.'%')
->orWhere('article_type','like','%'.$contributor_id.'%')
->orwhere('article_tag','like','%'.$contributor_id.'%');
})->whereBetween('id', [$end, $start-1])
->where('article_active',1)
->orderBy('id', 'desc')
->take(10)
->get();
Alexey Mezenin did it before me.