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();
Related
I have a model stored in a variable like:
$user = User::where('name', 'like', $test)
->orderBy('name');
I would like to build another query where I can join $user. Can't find the right syntax to do it.
What am trying to achieve:
$numbers= Number::join($user, $users.id, '=', 'number.user_id')
->where('name', 'like', "%" . $validated['text'] . "%")])
->get();
Assuming you have typical hasMany/belongsTo relationships set up between User and Number models, this should work:
User::where("name", "like", $test)
->whereHas("numbers", function($q) {
$q->where("name", "like", "%$validated[text]%");
})
->with("numbers", function($q) {
$q->where("name", "like", "%$validated[text]%");
})
->get();
The where() method, of course, matches users with the desired name. The whereHas() method further restricts based on the relationship, looking only for users having numbers with a matching name. Assuming you want to retrieve those matching numbers, you have to do the same filter again on the eager load.
Try this,
$numbers= Number::whereHas('<Your Eloquent Model>',function($query)use($validated){
$query->where('name', 'like', "%" . $validated['text'] . "%")]);
}
->get();
Join can be written in this way
$records = User::select('users.*')
->where('users.name', 'like', $test)
->join('numbers', function($join) {
$join->on('users.id', '=', 'numbers.id')
->where('numbers.name', 'like', "%" . $validated['text'] . "%");
})
->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.
there is a lot of similar topics but couldn't find a solution for me. This query loads very slow.
public function getAllBids()
{
return Bid::with('user', 'group')
->join('auct_lots', function ($join) {
$join->on('bids.lot_id', '=', 'auct_lots.lot_id')
->where('auct_lots.company', 'LIKE', '%' . request('brand') . '%')
->where('auct_lots.model_name', 'LIKE', '%' . request('models') . '%')
->where('auct_lots.grade_en', 'LIKE', '%' . request('carGrade') . '%')
->where('auct_lots.auction_name', 'LIKE', '%' . request('auctions') . '%')
->where('auct_lots.model_type_en', 'LIKE', '%' . request('chassis') . '%')
->where('auct_lots.bid', 'LIKE', '%' . request('lots') . '%')
->where('auct_lots.lot_date', 'LIKE', '%' . request('date') . '%');
})
->orderBy('auct_lots.' . request('order_column'), request('order_type'))
->paginate(30);
}
I think the problem is that auct_lots has more than 40,000 records... But I'm not sure how to refactor this code to work faster.
When you are having large amount of data, it is better to use server side caching. This will improve performance very much faster.
Step 1: Create a Trait and write logic for store values in caching.
Ex:
trait Student{
public function storeStudentDataInCache(){
$students = Cache::rememberForever('studentList', function () {
return Student::
with(['class', 'exams'])
->where('is_published', 1)->orderBy('display_sequence', 'ASC')->get();
});
return $students;
}
}
Now in your controller call this method, this will return collection of data. So you do not need run sql queries all the time to get data. This method will run query only after one time. After that data will be stored in caching so it will get data's collection from caching text file.
Note: Whenever you update your data,please do not forget to delete this cache.
And you can also apply where condition for laravel collection or you can use filter method of collection to implement more filter logic.
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();
$data = Retour::where('status','=',3)->where('rma','LIKE', '%' .$searchquery.'%')->OrWhere('naam','LIKE', '%' .$searchquery.'%')->OrWhere('framenummer','LIKE', '%' .$searchquery.'%')->get();
What's wrong with this query?
It ignores the where status = 3..
and returns all the reconrds even where the status != 3..
Thanks in advance.
You should group orWhere() here with closure:
$data = Retour::where('status', 3)
->where(function($q) use($searchquery) {
$q->where('rma', 'like', '%'.$searchquery.'%')
->orWhere('naam', 'like', '%'.$searchquery.'%')
->orWhere('framenummer', 'like', '%'.$searchquery.'%');
})->get();
Use scopes in such cases. See https://laravel.com/docs/5.3/eloquent#local-scopes
public function scopeSearch($query, $searchQuery)
{
return $query->where('status',3)
->where('rma','LIKE', "%$searchQuery%")
->orWhere('naam','LIKE', "%$searchQuery%")
->orWhere('framenummer','LIKE', "%$searchQuery%");
}
and one more thing
its not OrWhere it is orWhere