transform() must be an instance of App\DigitalCase - php

public function index(Request $request) {
if ($request->has('show_type') && $request->show_type == 'deleted') {
$digital_cases = DigitalCase::onlyTrashed()->get();
} else {
$digital_cases = DB::table('digital_cases');
if ($request->has('caseName')) {
$digital_cases = $digital_cases->where('name', 'LIKE', $request->caseName . '%');
if ($request->has('addedBy')) {
$addedBy = $request->addedBy;
$digital_cases = $digital_cases->whereIn('added_by', function ($query) use ($addedBy) {
$query->select('id')->from('assistants')->where('firstname', 'LIKE', $addedBy . '%');
});
}
} else if ($request->has('addedBy')) {
$addedBy = $request->addedBy;
$digital_cases = $digital_cases->whereIn('added_by', function ($query) use ($addedBy) {
$query->select('id')->from('assistants')->where('firstname', 'LIKE', $addedBy . '%');
});
}
$digital_cases = $digital_cases->get();
}
$transformation = fractal()->transformWith(new DigitalCaseTransformer())->collection($digital_cases)->toArray();
return response()->json($transformation, 200);
}
I really tired of asking questions. But i have last problem is; i couldnt convert digital_cases to DigitalCase Model instance.
I got an error :
Type error: Argument 1 passed to App\Transformers\DigitalCaseTransformer::transform() must be an instance of App\DigitalCase, instance of stdClass given, called in
If it work in IF condition everything is ok. But when it work in ELSE condition it returns an error. How can i convert digital_cases variable to instance of DigitalCase ?
Laravel 5.6

Using $digital_cases = DB::table('digital_cases'); will not give you an instance (or Collection of) the DigitalCase Model. You need to use DigitalCase. To start a query that you can append conditional clauses to, begin with
$digital_cases = DigitalCase::query();
Then, continue appending clauses in the same way. When you pass a closure (->get(), etc), you'll end up with a Collection of DigitalCase Models (or a single DigitalCase if using ->first()).

You can really simplify and clean up the conditional queries using when:
DigitalCase::when($request->has('caseName'), function ($q) {
return $q->where('name', 'LIKE', request()->caseName . '%');
})->when($request->has('addedBy'), function ($q) {
return $q->whereIn('added_by', function ($query) {
$query->select('id')->from('assistants')->where('firstname', 'LIKE', request()->addedBy . '%');
});
}})->get();
That will yield the same result as all the if () { .. } else if () { .. }

Related

How to handle an empty search query in Laravel 9?

I'm currently trying to implement a search functionality in my Laravel 9 API. Unfortunately, when I leave an empty query the API returns absolutely nothing. Any idea what I'm doing wrong?
Route:
Route::get('/products/search/{title?}', 'searchTitle');
public function searchTitle(Request $request, $title = '')
{
$pageSize = $request->page_size ?? 10;
if ($title == '') {
return Product::query()->paginate($pageSize);
} else {
return Product::where('title', 'LIKE', "%$title%")
->paginate($pageSize);
}
}
I suggest you use Conditional Clauses (when), something like this:
return Product::when($title !== '', function (Builder $query, $title) {
return $query->where('title', 'LIKE', "%$title%");
})
->paginate($pageSize);
Or use the object assign to a variable and make the where
$product = Product::query();
if ($title !== '') {
$product->where('title', 'LIKE', "%$title%");
}
return $product->paginate($pageSize);

Filter a collection in Laravel

i want to filter a collection in order to return only items with fullname that is like the one given in parmaters
public function searchFriend($fullName){
return Auth::user()->friends->filter(function ($item) use ($fullName) {
return false !== stristr($item->friend->full_name, $fullName);
});
}
the function actually is not returning the correct results.
Instead of accessing the collection directly, you can do the filtering in SQL.
public function searchFriend($fullName){
return Auth::user()
->friends()
->where('full_name', 'like', '%'.$fullName.'%')
->get();
}
If you, for whichever reason, need to do it on the collection, then the problem with your current code is that $item represents the friend, so you're checking $item->friend->full_name instead of $item->full_name.
public function searchFriend($fullName){
return Auth::user()
->friends
->filter(function ($item) use ($fullName) {
return false !== stristr($item->full_name, $fullName);
});
}
I guess friend is a relationship to the User model so it could be
public function searchFriend($fullName)
{
return Auth::user()->friends()->whereHas('friend', function ($query) use ($fullName) {
$query->where('full_name', 'like', "%{$fullName}%");
})->get();
}
If you have first_name and last_name in User model then you can use concat.
public function searchFriend($fullName)
{
return Auth::user()->friends()->whereHas('friend', function ($query) use ($fullName) {
$query->whereRaw("concat(first_name, ' ', last_name) like ?", ["%{$fullName}%"]);
})->get();
}

How to filter all and specific fields using Laravel Eloquent?

I want to refactor my source code when filtering records in all and specific fields.
Currently, I'm filtering all fields by passing 'search' in my request:
GET request: /api/users?search=
public function index(Request $request) {
$search = request("search") ?? "";
$users = $users->where(function ($query) use ($search) {
$query->where('code', "like", "%" . $search . "%");
$query->orWhere("first_name", "like", "%" . $search . "%");
$query->orWhere("last_name", "like", "%" . $search . "%");
$query->orWhereHas('department', function ($q) use ($search) {
$q->where('name', "like", "%" . $search . "%");
});
});
return $users->paginate(10);
}
I tried to follow this article, and now my GET request should be: /api/users?first_name=Juan&last_name=Cruz
Should I pass all request like /api/users?all=Juan to filter all fields at once?
What is the best approach when applying this kind of functionality?
If you know any acticles/resources which can serve as my reference, it would be a great help.
If you are following the article you shared, your url should look like /users?name=John&last_name=Doe&code=123
Then, you just call User::filter($filters)->get(), and it will automatically apply your query string filters to the query.
If you dont want to implement the filters functionality, you can use eloquent when method. It only apply the filter when a given condition is true.
public function index(Request $request) {
$query = User::query();
$query = $query->when(request('code'), function($query) {
$query->where('code', "like", '%'.request('code').'%')
})
->when(request('first_name'), function($query) {
$query->where('first_name', 'like', '%'.request('first_name').'%');
})
->when(request('last_name'), function($query) {
$query->where('last_name', 'like', '%'.request('last_name').'%');
})
->when(request('department'), function($query) {
$query->where('last_name', 'like', '%'.request('last_name').'%');
})
->when(request('department'), function($query) {
$query->whereHas('department', function($query) {
$query->where('name', 'like', '%'.request('department').'%');
});
});
return $query->paginate(10);
}

Laravel filter results in query based on post

I am using the laraval model to query results from several tables. Now I do have this function:
public function index(Request $request)
{
$roles = Roles::withcount('permissions')
->withcount('users')
->orderBy('name')
->get();
return view('UserManagement::roles.overview', compact('roles'));
}
$request is filled with the filter I want to append. But how to set a filter including pagination as I can't append the Roles with ->paginate()
Maybe somebody can help me on this one?
Thanks to Luis for pointing me to the right direction:
$search = $request->has('search') ? $request->search : null;
$roles = Roles::withcount('permissions')
->withcount('users')
->when($search, function ($query, $search) {
return $query->where('slug', 'like', '%' . $search . '%');
})
->orderBy('name')
->paginate(20);
you need to use a conditional clause
$roles = Roles::withcount('permissions')
->withcount('users')
->when($request->field_you_want_to_filter, function ($query, $request) {
return $query->where('field_you_want_to_filter', $request->field_you_want_to_filter);
})
->orderBy('name')
->paginate(20);

How to get only the searched data with where clause?

$data['ads'] = PostAd::where('category_id',$id)
->orwhere('district_id','LIKE','%'.$location.'%')
->orWhere('condition','LIKE','%'.$condition.'%')
->orWhere('price','>='.$min_price)
->orWhere('price','<='.$max_price)
->orWhere('fuel',$fuel)
->orWhere('anchalorpradesh',$anchal)
->orWhere('mileage',$mileage)
->orWhere('kilometers',$kilometers)
->orWhere('engine',$engine)
->get();
i want to show data whose category_id is $id. But whenever i try to search it shows me all the data in the database. Suppose i want to search data whose kilometer is 24. There is only one data whose kilometer is 24. But instead of showing that one data it shows me all the data in database.
Try something like this, adding conditional optionally based on search parameters choosen
$query = PostAd::query();
if ( isset($id) ) {
$query = $query->where('category_id',$id);
}
if ( isset($location) ) {
$query = $query->where('district_id', 'LIKE', '%' . $location . '%');
}
if ( isset($condition) ) {
$query = $query->where('condition', 'LIKE', '%' . $condition. '%');
}
$result = $query->get();
You can use the when method to conditionally add clauses to your queries depending on a value passing a “truth” test:
PostAd::query()
->when($request->get('category_id'), function ($query, $categoryId) {
$query->where('category_id', '=', $categoryId);
})
->paginate();
The closure you pass as the second argument will receive two arguments: a query builder instance that you can modify, and the value you passed as the first parameter to the when method.
You can also take this one step further and move your filtering logic to a dedicated class:
class PostAdFilters
{
protected $request;
protected $builder;
public function __construct(Request $request)
{
$this->request = $request;
}
public function apply(Builder $builder)
{
$this->builder = $builder;
foreach ($this->request->query() as $key => $value) {
// Convert something like `category_id` to `filterByCategoryId`
$methodName = 'filterBy' . Str::studly($key);
if (method_exists($this, $methodName)) {
// If the method exists, call it
call_user_func([$this, $methodName], $value);
}
}
// Return the modified query builder
return $this->builder;
}
private function filterByCategoryId($value)
{
$this->builder->where('category_id', '=', $value);
}
private function filterByKilometers($value)
{
$this->builder->where('kilometers', '=', $value);
}
// And so on...
}
class PostAd extends Model
{
public function scopeFilters(Builder $query, PostAdFilters $filters)
{
return $filters->apply($query);
}
}
You can then inject this class in your controller method, and apply it to your model:
public function search(PostAdFilters $filters)
{
return PostAd::filter($filters)->paginate();
}
This approach is based on https://laracasts.com/series/eloquent-techniques/episodes/4

Categories