I have this query:
$orders = Order::with(['company', 'products', 'user', 'status', 'seller'])->orderBy('id', 'DESC')->select('orders.*');
And it returns the relevant results as expected in a yajra datatable instance.
Now I would like to narrow down this result even more. I use it this way:
$orders = $orders->whereHas('user', function ($q) use ($request){
$q->searchFullName($request->seller);
});
I have created a scope in the model and it works for another function on my website. However it returns no results when calling it like that.
Even if I call the whereHas using a where statement, still the result is empty:
$orders = $orders->whereHas('user', function ($q) use ($request){
$q->where('first_name', 'like', '%'.$request->seller.'%');
});
The seller parameter is not empty. Even if I use a hardcoded string, the results are always empty.
The searchFullName method:
public function scopesearchFullName($query, $value){
return $query->where('first_name', 'LIKE', "%$value%")
->orWhere('middle_name', 'LIKE', "%$value%")
->orWhere('last_name', 'LIKE', "%$value%");
}
Full controller:
public function listOrdersData(Request $request)
{
if(!$request->ajax())
return Redirect::route('/');
$loggedUser = Auth::user();
if($loggedUser->hasRole('Super Administratör'))
$orders = Order::with(['company', 'products', 'user', 'status', 'seller'])->orderBy('orders.id', 'DESC')->select('orders.*');
else
$orders = Order::with(['company', 'products', 'user', 'status', 'seller'])->where('company_id', $loggedUser->company_id)->orderBy('id', 'DESC')->select('orders.*');
if (!empty($request->seller) && $request->seller != 'all') {
$orders = $orders->whereHas('user', function ($q) use ($request){
$q->searchFullName($request->seller);
});
}
return DataTables::of($orders)
->addColumn('products', function($orders) {
$products = "";
foreach($orders->products as $product)
$products = $products . $product->name . "<br>";
return $products;
})
->editColumn('company', function($orders){ return $orders->company->name; })
->editColumn('price', '{{$price}} kr')
->editColumn('user', function($orders){
return $orders->user->full_name;
})
->addColumn('seller', function($orders){
return $orders->seller->full_name;
})
->addColumn('status', function($orders){
return '<span class="chip lighten-4 purple purple-text">'. $orders->status->localized . '</span>';
})
->addColumn('contract', '<i class="material-icons">file_download</i>')
->addColumn('edit', '<i class="material-icons">edit</i>')
->rawColumns(['products', 'status', 'edit', 'contract'])
->make(true);
}
The issue is with scope method
public function scopesearchFullName($query, $value){
return $query->where('first_name', 'LIKE', "%".$value."%")
->orWhere('middle_name', 'LIKE', "%".$value."%")
->orWhere('last_name', 'LIKE', "%".$value."%");
}
Also make sure that only those user record returns who has orders.
Also for searching sellers order
$orders = $orders->whereHas('seller', function ($q) use ($request){
$q->searchFullName($request->seller);
});
so in Order model
public function seller()
{
return $this->belongsTo(User::class, 'seller_id', 'id');
}
Related
I don't know how to add $countries to the State queryString below. Could you help me
public function index(){
// $countries = Country::all();
$perPage = Requests::input('perPage') ?: 5;
return Inertia::render('State/Index',[
'states' => State::query()
->when(Requests::input('search'), function($query, $search){
$query->where('name', 'like', "%{$search}%");
})
->paginate($perPage)
->withQueryString(),
'filters' => Requests::only(['search', 'perPage']),
]);
}
You are missing $search variable.
And ->when($condition, function ...) need a true/false condition.
public function index(Request $request){
// $countries = Country::all();
// probably best to add validation at this point
$validated = $request->validate($rules);
$perPage = $request->input('perPage', 5); // set 5 as default when empty
$search = $request->input('search');
return Inertia::render('State/Index',[
'states' => State::query()
->when(!empty($search), function($query, $search){
$query->where('name', 'like', "%{$search}%");
})
->paginate($perPage)
->withQueryString(),
'filters' => $request->only(['search', 'perPage']),
]);
}
Here is my method available in the controller
public function getProductListAll(){
$products = Product::with('property')
->whereStatus(1)
->where('show', 1)
->where('code', '!=', 1)
->where('is_roketable',true)
->with(['prices_roket' => function ($q) {
return $q->whereNull('user_id');
}]);
$products = $products->whereIn('product_type', ['education', 'consultancy', 'startup']);
$data['products'] = $products->select([
'id', 'name', 'image', 'commission', 'price',
'buy_now', 'type', 'short_desc', 'pricing_desc',
'offer_status', 'period_status', 'period', 'period_frequency',
'endpoint', 'product_type', 'unique_id', 'discount_show_status',
'annual_payment', 'pre_register', 'privacy_status', 'privacy',
'sg_project', 'last_pre_register_date', 'product_desc',
'product_consulting', 'product_status',
])->get();
return response()->json($data);
}
and here is the relationship in my model.
return $this->hasMany(ProductPrice::class)->select('price','created_at','user_id','offer_id')
->orderBy('price')
->where(function ($q) {
$q
->where(function ($q2) {
$q2->whereNull('offer_id');
})
->orWhere(function ($q2) {
$q2->whereNotNull('offer_id');
$q2->where('user_id', auth()->user() ? auth()->user()->id : 0);
});
});
I tried to change my relationship and rewrite it, but when I write select, I cannot access any data. When I remove select, they all come. I can't select at prices relationship.
You can not use ->select() inside your model relationship.
Instead what you can do to limit the selection is by adding it into ->with()
For example
$products = Product::query()
->with(['property' => function ($q) {
$q->select(['price','property.created_at','user_id','offer_id']);
}])
->where( ... )
// no need to add property 'price' inside this select
->select(['id', 'name', 'image', 'commission' ... ])
->get();
public function scopeSearch($query, $value)
{
$searchValues = explode(' ', $value);
if (!$value) return $query;
return $query->where(function ($q) use ($searchValues) {
foreach ($searchValues as $token) {
$q->orWhere('name', 'like', "%{$token}%");
$q->orWhere('street', 'like', "%{$token}%");
}
});
}
I want to search the data. This model also has
public function brands()
{
return $this->belongsToMany(Brand::class, 'dealer_brands');
}
public function province()
{
return $this->belongsTo(Province::class);
}
How can I get data from the relastionship. Like Dealer(model) has data Nmae = josh , brand_id = 1 {brand.name = samsung} , province_id = 2 (province.name = "aligora"). When I search Josh Samsung Alogora, I want to ge the data. When I only search aligora, I want to get the data of model having province aligora. hOW CAN I MODIFY CODE?
looking at your model relationships. This may work for you
public function scopeSearch($query, $value)
{
if (!$value) return $query;
$searchValues = explode(' ', $value);
return $query->where(function ($q) use ($searchValues) {
foreach ($searchValues as $token) {
$q->where('name', 'like', "%{$token}%")
->orWhere('street', 'like', "%{$token}%")
->orWhereHas('brands', function ($sub_q) use ($searchValues) {
$sub_q->where('name', 'like', "%{$token}%")
->orWhere('street', 'like', "%{$token}%");
})
->orWhereHas('province', function ($sub_q) use ($searchValues) {
$sub_q->where('name', 'like', "%{$token}%")
->orWhere('street', 'like', "%{$token}%");
});
}
});
}
I have no idea about column names in related tables so repeating name and street. you can change as per requirement
I have the following relations in my Laravel application
class Item extends Model
{
public function category()
{
return $this->belongsTo('App\Category');
}
}
and
class Category extends Model
{
public function item()
{
return $this->hasMany('App\Item');
}
}
I want to implement search functionality so I have created the following Eloquent query:
$items = Item::where('item_type', '=', 'type1')
->where(function($query) use ($q) {
$query->where('item_name','LIKE','%'.$q.'%')
->orWhere('item_description','LIKE','%'.$q.'%');
})
->paginate(10);
This is working as expected and returns the search results for 'q' based on the name and the description of the item.
As a next step, I would like to also search for the category_name. Because of the relation, I have the category_id stored in the Items table, but I would like to use the category_name in my Eloquent query.
Anyone could provide some help?
Based on feedback received, I tried:
Suggestion 1:
$items = Item::where('item_type', '=', 'type1')
->where(function($query) use ($q) {
$query
->where('item_name', 'LIKE' ,'%'.$q.'%')
->orWhere('item_description', 'LIKE' ,'%'.$q.'%');
})
->whereHas('category', function (Category $query) use ($q) {
$query->where('category_name', $q);
})
=> this gives following error message:
Argument 1 passed to
App\Http\Controllers\ItemController::App\Http\Controllers{closure}()
must be an instance of App\Http\Controllers\App\Category, instance of
Illuminate\Database\Eloquent\Builder given
Suggestion 2:
$items = Item::where('item_type', '=', 'type1')
->where(function($query) use ($q) {
$query
->where('item_name', 'LIKE' ,'%'.$q.'%')
->orWhere('item_description', 'LIKE' ,'%'.$q.'%');
})
->whereHas('category', function ($query) use ($q) {
$query->where('category_name', $q);
})
=> this does not result any search result anymore (also not for item_name and item_description).
Solution
$items = Item::where('item_type', '=', 'type1')
->where(function($query) use ($q) {
$query
->where('item_name', 'LIKE' ,'%'.$q.'%')
->orWhere('item_description', 'LIKE' ,'%'.$q.'%');
})
->orWhereHas('category', function ($query) use ($q) {
$query->where('category_name', $q);
})
->sortable(['id' => 'desc'])
->paginate(10);
As you already described relation to Category in your Item model, you have to use just whereHas method:
$items = Item::where('item_type', '=', 'type1')
->where(function($query) use ($q) {
$query->where('item_name','LIKE','%'.$q.'%')
->orWhere('item_description','LIKE','%'.$q.'%');
})
->orWhereHas('category', function ($query) use ($q) {
$query->where('category_name', 'LIKE', "%$q%");
})
->paginate(10);
You could add a whereHas and constrain it. For example:
$items = Item::where('item_type', '=', 'type1')
->where(function($query) use ($q) {
$query->where('item_name','LIKE','%'.$q.'%')
->orWhere('item_description','LIKE','%'.$q.'%');
})
->whereHas('category', function($query) {
$query->where('category_name', 'name');
})
->paginate(10);
I have a posts model that has this relationship to the User:
public function author()
{
return $this->belongsTo(User::class, 'user_id');
}
i am building a search function and I have this code
public function index(Request $request)
{
$search = $request->search;
$filter = $request->filter;
$append = array();
$posts = Post::with('author')->with('categories')->latest();
if($search){
switch ($filter) {
case 'username':
$posts->author->where('username', 'LIKE', '%'. $search . '%');
break;
}
$append += array('search' => $search);
$append += array('filter' => $filter);
}
$posts = $posts->paginate(3);
$posts->appends($append);
return view('core.blog.posts.index', compact('posts'));
}
I get
Undefined property: Illuminate\Database\Eloquent\Builder::$author
How do I add where that looks for author based on his username? I must be able to add this condition in an if case
You want to use whereHas() to searched based on a relation. This will return only posts that have an author with the username.
switch ($filter) {
case 'username':
$posts->whereHas('author', function($q) use($search) {
$q->where('username', 'LIKE', '%'. $search . '%');
});
break;
}
UPDATE
If you need conditional where, you can do this:
$postSelector = Post::with('categories');
if($search){
switch ($filter) {
case 'username':
$postSelector->with(['author' => function($q) use($search) {
$q->where('username', 'LIKE', '%'. $search . '%');
}]);
break;
}
$posts = $postSelector->get();