Laravel sort model by one to many relationship - laravel

I have two models Location and Danger
Danger has two fields location_id and user_id it simply save users report about locations
btw Danger has a one to many relation with Location
the question is
how can I sort locations with count of it's danger in a search form
here is my form:
$locations = Location::latest();
if ($request->get('q')) {
$q = $request->get('q');
$locations->where('desc', 'like', '%' . $q . '%')
->orWhere('name', 'like', '%' . $q . '%');
}
$locations=$locations->paginate(12);
return view('list')->with(compact('locations'));

If your location has many danger and your relation is named dangers then you can use withCount() for sorting as:
$locations = Location::withCount('dangers');
if ($request->get('q')) {
$q = $request->get('q');
$locations->where('desc', 'like', '%' . $q . '%')
->orWhere('name', 'like', '%' . $q . '%');
}
$locations->orderBy('dangers_count', 'desc')
$locations=$locations->paginate(12);

this might work.
$locations = Location::latest();
if ($request->get('q')) {
$q = $request->get('q');
$locations->where('desc', 'like', '%' . $q . '%')
->orWhere('name', 'like', '%' . $q . '%');
$locations->sortBy(function($item, $key){
return $location->danger()->count();
})
}
$locations=$locations->paginate(12);
return view('list')->with(compact('locations'));

Related

How to get foreign key data in main field Laravel

I have a problem connecting to the data for searching the customer's name because I only identify the id as a foreign key. How can I get data from the customer table? I tried using a join table but no got no result.
public function render()
{
$search = $this->searchTerm;
$data = Order::with('customer')->where('user_id', Auth::id())
->where(function ($query) use ($search) {
$query->where('customer_id', 'like', '%' . $search . '%') // <- this field linked in customers table to get name of customer
->orWhere('orderNumber', 'like', '%' . $search . '%');
})->orderBy('id', $this->sortDirection)->paginate(9);
return view('livewire.dashboard.orders.list-order', compact('data'));
}
If I am right I think you are trying to search for customer name through customer relationship
You can do it like this:
$search = $this->searchTerm;
$data = Order::where('user_id', Auth::id())->with(['customer' =>
function($query) use($search){
$query->where('name','like', '%' . $search . '%')
->orWhere('orderNumber', 'like', '%' . $search . '%');
}])->orderBy('id', $this->sortDirection)->paginate(9);

Adding secondary query to query based on parameter in laravel

I am trying to do a complex query based on the input fields of the form.
public function search(Request $request){
$borrado =
$activo = 0;
$models = array();
$escandallos = Scandal::all();
foreach ($escandallos as $escandallo){
if (in_array($escandallo->modelo, $models)) {
}else{
array_push($models, $escandallo->modelo);
}
}
$query = Model::where('modelo', 'like', '%' . $request['modelo'] . '%')
->where('prototipo', 'like', '%' . $request['prototipo'] . '%')
->where('oficial', 'like', '%' . $request['modofi'] . '%')
->where('usuario_realiza', 'like', '%' . $request['usuario'] . '%')
->where('tipo', 'like', '%' . $request['tipo'] . '%')
->where('activa', 'like', '%' . $activo . '%');
if($request['referencia'] || $request['proveedor']){
/** Here i want to do this DB:raw where in clause if reference or provider is in request and need to search in other table*/
$query->DB::raw("where (id_escandallo,id_version) in (select id_escandallo,id_version from escandallo_p where referencia ='".$request['referencia']. "' and proveedor ='".$request['proveedor']."'");
}
$query->orderBy('modelo','desc');
$query->orderBy('id_version','asc');
$scandals = $query->paginate(100);
dd($scandals);
return view('designdoc.escandallos',['scandals'=> $scandals],['models'=>$models]);
}
This return this error:
Property [DB] does not exist on the Eloquent builder instance.
Thank you in advance, any help would be appreciated.
Best regards.
Use ->whereRaw()
$query->whereRaw(...);
also, you can simplify this part
if($request['referencia'] || $request['proveedor']){
$query->whereRaw(...); // but dont use 'where' in the string, its already prepended
}
to this
$query->when($request['referencia'] || $request['proveedor'], function ($q) use ($request) {
$q->whereRaw(...)
});
it is good so that you can chain it with previous command

searching on name instead of id on sql

I have search input in my products page. I can search on name on description and on category if I type the id but that's not really practical how i change this sql so i can search on the name of the category instead of the id.
DB i have Products | name,description,category_id
Categories | id,name
public function scopeFilter($query,array $filters){
if ($filters['search'] ?? false){
$query
->where('name', 'like', '%' . request('search') . '%')
->orWhere('description', 'like', '%' . request('search') . '%')
->orWhere('category_id', 'like', '%' . request('search'). '%');
}
}
Since the category is a related model search on the relationship:
public function scopeFilter($query,array $filters){
if ($filters['search'] ?? false){
$query
->where('name', 'like', '%' . request('search') . '%')
->orWhere('description', 'like', '%' . request('search') . '%')
->orWhereHas('category', function ($q) {
$q->where('name','like', '%' . request('search'). '%'
});
}
}
This is assuming you have defined your relationship in your model.
Since the category is a related model search on the relationship AND I suggest using this code: ‌
public function scopeFilter($query,array $filters) {
if ($filters['search'] ?? false){
return $query->where('name', 'like', '%' . request('search') . '%')
->orWhere('description', 'like', '%' . request('search') . '%')
->orWhereHas('category', function ($q) {
$q->where('name','like', '%' . request('search'). '%');
});
}
return $query;
}

Laravel Eloquent query ignoring column value

On my search method in the Models\Article::class I'm able to get all the results, even in the multiple relations with Categories and Tags, but the issue, that I've been trying to solve, unsuccessfully, is that I just want the results for the published articles – my db column for this is a bool 'active'.
I've tried different approaches by switching the ->where('active', 1) clause around but the results are the same. It brings all the active and non active.
I have in development 8 articles but only 7 with active = 1. When I perform the search, the response sends all the 8, ignoring the where('active', 1) clause. Probably I'm missing or messing something here in the following method:
// Method in the Article Model class
public function getSearchResults($query)
{
return $this->where('active', 1)->where('start_publishing', '<=', Carbon::now())
->where('external_reference', 'LIKE', '%' . $query . '%')
->orWhere('byline', 'LIKE', '%' . $query . '%')
->orWhere('published_by', 'LIKE', '%' . $query . '%')
->orWhere('title', 'LIKE', '%' . $query . '%')
->orWhere('subhead', 'LIKE', '%' . $query . '%')
->orWhere('lead_story', 'LIKE', '%' . $query . '%')
->orWhere('content', 'LIKE', '%' . $query . '%')
->orWhere('meta_keywords', 'LIKE', '%' . $query . '%')
->with('categories')->orWhereHas('categories', function ($q) use ($query) {
$q->where('title', 'LIKE', '%' . $query . '%');
})
->with('documents')->orWhereHas('documents', function ($q) use ($query) {
$q->where('doc_title', 'LIKE', '%' . $query . '%');
//$q->where('doc_description', 'LIKE', '%'.$query.'%');
})
->with('tags')->orWhereHas('tags', function ($q) use ($query) {
$q->where('name', 'LIKE', '%' . $query . '%');
})
->with('images')
->orderBy('type', 'desc')
->orderBy('updated_at', 'desc')
->paginate(15);
}
Thanks in advance fr any help here on this issue.
Result is because you are use orWhere Criteria. For fix it use this
$this->where('active', 1)
->where('start_publishing', '<=', Carbon::now())
->where(function($q) use ($query) {
$q->where('external_reference', 'LIKE', '%' . $query . '%') // the $q here is required
->orWhere('byline', 'LIKE', '%' . $query . '%')
->orWhere('published_by', 'LIKE', '%' . $query . '%')
->orWhere('title', 'LIKE', '%' . $query . '%')
->orWhere('subhead', 'LIKE', '%' . $query . '%')
->orWhere('lead_story', 'LIKE', '%' . $query . '%')
->orWhere('content', 'LIKE', '%' . $query . '%')
->orWhere('meta_keywords', 'LIKE', '%' . $query . '%');
})
->with('categories')->orWhereHas('categories', function ($q) use ($query) {
$q->where('title', 'LIKE', '%' . $query . '%');
})
->with('documents')->orWhereHas('documents', function ($q) use ($query) {
$q->where('doc_title', 'LIKE', '%' . $query . '%');
//$q->where('doc_description', 'LIKE', '%'.$query.'%');
})
->with('tags')->orWhereHas('tags', function ($q) use ($query) {
$q->where('name', 'LIKE', '%' . $query . '%');
})
->with('images')
->orderBy('type', 'desc')
->orderBy('updated_at', 'desc')
->paginate(15);
Ok, after Davit's suggestion, which at the beginning seemed like to work, but it was the query I was doing that was "faking" the results, I finally managed to make it work.
Taking the code David suggested, I made a few changes, through the logic of how the query gets constructed and ended up with a final working method that will return only the active Articles matching the "query" criteria from the request. Below the final method code:
// Method in the Article Model class
public function getSearchResults($query)
{
return $this->where('active', 1)
->where('start_publishing', '<=', Carbon::now())
->where(function ($q) use ($query) {
$q->where('external_reference', 'LIKE', '%' . $query . '%')
->orWhere('byline', 'LIKE', '%' . $query . '%')
->orWhere('published_by', 'LIKE', '%' . $query . '%')
->orWhere('title', 'LIKE', '%' . $query . '%')
->orWhere('subhead', 'LIKE', '%' . $query . '%')
->orWhere('lead_story', 'LIKE', '%' . $query . '%')
->orWhere('content', 'LIKE', '%' . $query . '%')
->orWhere('meta_keywords', 'LIKE', '%' . $query . '%');
$q->with('categories')->orWhereHas('categories', function ($q) use ($query) {
$q->where('title', 'LIKE', '%' . $query . '%');
});
$q->with('documents')->orWhereHas('documents', function ($q) use ($query) {
$q->where('doc_title', 'LIKE', '%' . $query . '%');
//$q->where('doc_description', 'LIKE', '%'.$query.'%');
});
$q->with('tags')->orWhereHas('tags', function ($q) use ($query) {
$q->where('name', 'LIKE', '%' . $query . '%');
});
})
->with('categories')
->with('tags')
->with('images')
->distinct()
->orderBy('type', 'desc')
->orderBy('updated_at', 'desc')
->paginate(15);
}

Laravel 4: A where and whereIn inside a whereHas using Eloquent

Laravel 4 - advanced Where
I'm trying to retrieve Posts that have a $keyword like a certain Companion and besides that I want to retrieve the Posts the have a linking title or content as the $keyword.
But when I try to use a where or whereIn inside a whereHas the query doesn't take these into account. When the state is 0 (not visible) or not inside the category 1 the Post item should not get selected.
$companion_id = Companion::where('name', 'LIKE', '%' . $keyword . '%' )->lists('id');
The code block below has to do two things:
Search for Post items with a title or content like the $keyword
and search for Post items that have Companions like the $keyword
code:
$results = Post::whereHas('companions', function($query) use($companion_id)
{
$query->whereIn('companions.id', $companion_id)
->where('state', '=', 1)
->whereIn('category_id', array(1));
})
->whereIn('category_id', array(1))
->orwhere('title', 'LIKE', '%' . $keyword . '%' )
->orWhere('content', 'LIKE', '%' . $keyword . '%' )
->where('state', '=', '1')
->orderBy('menu_order', 'desc')
->get();
The code above retrieves data succesfully except for the where and whereIn parts inside the whereHas.
Who can help me out?
wrap your orWhere clauses in (..)
you don't need where and whereIn in the whereHas closure, since it queries companions table
you don't need whereIn for category_id, unless you want to pass multiple ids there
.
$results = Post::whereHas('companions', function($query) use($companion_id)
{
$query->whereIn('companions.id', $companion_id);
})
->whereIn('category_id', array(1)) // why not where(..) ?
->where(function ($q) use ($keyword) {
$q->where('title', 'LIKE', '%' . $keyword . '%' )
->orWhere('content', 'LIKE', '%' . $keyword . '%' );
})
->where('state', '=', '1')
->orderBy('menu_order', 'desc')
->get();
Thanks to Jarek Tkaczyk.
His answer was almost correct. All I had to do was wrap the where inside a orWhere. Now I get the Posts that has a Companion like the $keyword and I get the Posts that has the $keyword inside the content or title.
$results = Post::whereHas('companions', function($query) use($companion_id)
{
$query->whereIn('companions.id', $companion_id)
->where('state', '=', '1');
})
->orWhere( function($q) use ( $keyword ) {
$q->where('title', 'LIKE', '%' . $keyword . '%' )
->orWhere('content', 'LIKE', '%' . $keyword . '%' );
})
->whereIn('category_id', array(1, 3))
->where('state', '=', '1')
->orderBy('menu_order', 'desc')
->get();

Resources