Laravel Eloquent add 'where' clause in the query by condition - laravel

I want to add a condition first before adding another where query it but seems that laravel won't allow. I want something like the following.
function index()
{
$role = Auth::user()->role; //SEE_ALL, SEE_DEPT_A, SEE_DEPT_B
$q = Input::get('q');
if ($q != "") {
$user = User::where('name', 'LIKE', '%' . $q . '%')
->orWhere('email', 'LIKE', '%' . $q . '%')
->orderBy('name');
if ($role == "SEE_DEPT_A") {
$user->where('user_department', "A");
}
$user->paginate(10)->appends('q', $q);
}
return view('users.index')->with('data', ['users' => $user, 'q' => $q]);
}

You should use the when() function :
$user = User::where('name', 'LIKE', '%' . $q . '%')
->orWhere('email', 'LIKE', '%' . $q . '%')
->orderBy('name')
->when($role == "SEE_DEPT_A", function($query){
return $query->where('user_department', "A");
})->paginate(10)->appends('q', $q);

You need to assign the statement where you used where clause:
if ($role == "SEE_DEPT_A") {
$user = $user->where('user_department', "A");
}
And if the if statement does not run (in case of false), it will throw an error about $user being undefined

You can insert multi conditions like this:
$user_model = User::where('name', 'LIKE', '%' . $q . '%')
->orWhere('email', 'LIKE', '%' . $q . '%')
->orderBy('name');
if ($role == "SEE_DEPT_A") {
$user_model = $user_model->where('user_department', "A");
}
...
//other if statements
...
$users = $user_model->paginate(10)->appends('q', $q);

Related

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

Search in all columns (Eloquent)

I am doing a method to search in all the columns of the table
$busqueda = $request->input('buscar');
/* Get columns */
$client = new Crmclient;
$table = $client->getTable();
$columns = \Schema::getColumnListing($table);
foreach ($columns as $column) {
$users_client = Crmclient::where('user_id', Auth::id())
->where($column, 'like', '%' . $busqueda . '%')
->orWhere('user_id_subaccount', Auth::id())
->where($column, 'like', '%' . $busqueda . '%')
->get();
}
whats wrong? I can get all the columns and if I do var_dump inside the loop in some interactions it looks for me and in others not, but finally I get the empty array
Try this
$columns = \Schema::getColumnListing((new Crmclient)->getTable());
$users_client = Crmclient::where(function ($query) {
$query->where('user_id', Auth::id())->orWhere('user_id_subaccount', Auth::id());
})->where(function ($query) use ($columns, $busqueda) {
foreach ($columns as $column) {
$query->orWhere($column, 'like', "%{$busqueda}%");
}
})->get();

laravel search multiple keywords

I have a problem with search form on my website. Basically, when user will type multiple keywords to search form (e.g. business card ) then search result will show all images from keyword 1 (e.g. business) and all images from keyword2 (e.g. card). This is bad, the search form is not relevant at all. Can you please look at the code down bellow and help me fix it so the search form will show only images with both keywords together (keyword1 + AND + keyword2).
public function search($search, $category = null, $timeframe = null)
{
$extends = explode(' ', $search);
if ($category) {
$categoryId = $this->category->whereSlug($category)->first();
}
$images = $this->posts($category, $timeframe)->where('title', 'LIKE', '%' . $search . '%')
->orWhere('tags', 'LIKE', '%' . $search . '%')
->whereNull('deleted_at')->whereNotNull('approved_at')->orderBy('approved_at', 'desc');
foreach ($extends as $extend) {
if (isset($categoryId)) {
$images->whereCategoryId($categoryId)->Where('tags', 'LIKE', '%' . $extend . '%')->whereNotNull('approved_at')->whereNull('deleted_at')
->whereCategoryId($categoryId)->orWhere('title', 'LIKE', '%' . $search . '%')->whereNotNull('approved_at')->whereNull('deleted_at')
->whereCategoryId($categoryId)->orWhere('image_description', 'LIKE', '%' . $search . '%')->whereNotNull('approved_at')->whereNull('deleted_at');
} else {
$images->orWhere('tags', 'LIKE', '%' . $extend . '%')->whereNotNull('approved_at')->whereNull('deleted_at')
->orWhere('title', 'LIKE', '%' . $search . '%')->whereNotNull('approved_at')->whereNull('deleted_at')
->orWhere('image_description', 'LIKE', '%' . $search . '%')->whereNotNull('approved_at')->whereNull('deleted_at');
}
}
return $images = $images->with('user', 'comments', 'favorites')->whereNotNull('approved_at')->whereNull('deleted_at')->paginate(perPage());
}
When you use the % sign before and after the search query, you say "give me anything with that items", if you want your system to search and give results exactly as per what the user has entered, you should use only the key phrase. try the code below.
public function search($search, $category = null, $timeframe = null)
{
$extends = explode(' ', $search);
if ($category) {
$categoryId = $this->category->whereSlug($category)->first();
}
$images = $this->posts($category, $timeframe)
->where('title', 'LIKE', "$search")
->orWhere('tags', 'LIKE', "$search")
->whereNull('deleted_at')
->whereNotNull('approved_at')
->orderBy('approved_at', 'desc');
foreach ($extends as $extend) {
if (isset($categoryId)) {
$images->whereCategoryId($categoryId)->Where('tags', 'LIKE', "$search")
->whereNotNull('approved_at')->whereNull('deleted_at')
->whereCategoryId($categoryId)->orWhere('title', 'LIKE', "$search")
->whereNotNull('approved_at')->whereNull('deleted_at')
->whereCategoryId($categoryId)
->orWhere('image_description', 'LIKE', "$search")
->whereNotNull('approved_at')->whereNull('deleted_at');
}
else {
$images->orWhere('tags', 'LIKE', "$extend")
->whereNotNull('approved_at')->whereNull('deleted_at')
->orWhere('title', 'LIKE', "$search")
->whereNotNull('approved_at')->whereNull('deleted_at')
->orWhere('image_description', 'LIKE', "$search")
->whereNotNull('approved_at')->whereNull('deleted_at');
}
}
return $images = $images->with('user', 'comments', 'favorites')
->whereNotNull('approved_at')
->whereNull('deleted_at')
->paginate(perPage());
}

Laravel sort model by one to many relationship

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'));

Laravel eloquent search on fields of related model

I have an eloquent models as,
User : users(id, username, password, email, status)
Profile : profiles(id, user_id, first_name, last_name, gender, dob)
In the controller logic, I am eagerly loading the Profile model.
I can do this,
$user = User::with('Profile')->get();
or
$user = User::with('Profile')->where('status', '1')->get();
but how to do something like,
$user = User::with('Profile')->where('status', '1')->where('gender', 'Male')->get();
That's where whereHas comes in handy:
$user = User::with('Profile')->where('status', 1)->whereHas('Profile', function($q){
$q->where('gender', 'Male');
})->get();
Basically it adds the condition that the user needs to have a profile with gender = Male
If you want to search multiple columns in relation model.
$searchText = 'test text';
Product::with('owner')->where(function($query) use ($searchText)
{
$query->where('product_name', 'LIKE', '%' . $searchText . '%');
$columns = ['product_code', 'place_location', 'remark'];
foreach ($columns as $column ) {
$query->orWhere($column, 'LIKE', '%' . $searchText . '%');
}
$query->orWhereHas('owner', function($q) use ($searchText) {
$q->where(function($q) use ($searchText) {
$q->where('name', 'LIKE', '%' . $searchText . '%');
$q->orWhere('company_name', 'LIKE', '%' . $searchText . '%');
});
});
});
Let's say you've multiple relations
and you want to search records based on multiple relational columns value
User::with('associate')
->where('name', 'like', '%' . $input . '%')
->orWhere(function ($query) use ($input) {
$query->whereHas('associate', function ($q) use ($input) {
$q->where('first_name', 'like', '%' . $input . '%');
});
})
->orWhere(function ($query) use ($input) {
$query->with('roles')->whereHas('roles', function ($q) use ($input) {
$q->where('display_name', 'like', '%' . $input . '%');
});
})
->get();
Suppose, Your search input field name is q.
function name(Request $request){
$query = User::select();
if($request->q && $request->q !=''){
// if you search
$keyword = $request->q;
$query = User::with('Profile')->whereHas('Profile', function($q) use
($keyword){
$q->where('gender', 'like', "%{$keyword}%" );
});
}
$query->latest('id')->paginate();
}

Resources