Laravel Search Relations whereHas - laravel

I am trying to do a search on products but it does not return any results. I suspect it has something to do with the whereHas function but I just cannot figure it out. Here is my code:
My Relations:
Categories Model:
class Categories extends Eloquent {
public function product()
{
return $this->hasMany('Products')->orderBy('name');
}
}
Products Model:
class Products extends Eloquent {
public function category()
{
return $this->belongsTo('Category')->orderBy('name');
}
}
My search function:
public function search()
{
$search = Input::get('search');
$result = Products::where('name', 'LIKE', '%'. $search .'%')->get();
if ($result->first()) {
return View::make('groceries.index')
->with('categories', Categories::with('product')->orderBy('name', 'asc')
->whereHas('product', function($query) use ($search)
{
$query->where('name', 'LIKE', '%'.$search.'%');
}));
}
}
In the view:
#foreach ($categories as $category)
//do stuff
#foreach ($category->product as $products)
//Show results
#endforeach
#endforeach

You have to call get() to get the data.
And I think this will be more readable code.
public function search()
{
$search = Input::get('search');
$result = Products::where('name', 'LIKE', '%'. $search .'%')->get();
if ($result->first()) {
$categories = Categories::with('product')->orderBy('name', 'asc')
->whereHas('product', function($query) use ($search){
$query->where('name', 'LIKE', '%'.$search.'%');
})->get();
return View::make('groceries.index')
->with('categories', $categories);
}
}

Related

Query through a relationship - laravel DB

how do I get the same result for this when I use Query Builder DB
$categories = Category::with(['subcategory' => function ($query) {
return $query->where('status', true);
}])->where('status', true)->get();
Relationships
category
public function subcategory()
{
return $this->hasMany(Subcategory::class);
}
subcategory
public function category()
{
return $this->belongsTo(Category::class);
}
tables
categories
$table->id();
$table->string('name')->nullable();
subcategories
$table->id();
$table->foreignId('category_id')->constrained()->onDelete('cascade')-> onUpdate('cascade');
$table->string('name')->nullable();
I want to do a loop like this
foreach ($categories as $ctaegory){
$ctaegory->name
foreach ($ctaegory->subcategory as $subcategory){
$subcategory->name
}
}
My code works (Eloquent), but I want to use DB
Something like that:
DB::table('categories')
->join('subcategories', 'categories.id', '=', 'subcategories.category_id')
->where('subcategories.status', true)
->get();
I don't tested.
OR
Category::select("categories.*, subcategories.*")
->join("subcategories", "subcategories.category_id","=","categories.id")
->where('subcategories.status', true)
->get();

Laravel Eloquent pass Attribute to Relationship

I'm trying to load a relationship with eager loading. But, would like to pass an attribute to the relationship function.
(Laravel 6.x)
Model - taxChildren() requires an ID
public function taxChildren($moduleId)
{
return $this->hasMany($this, 'parent')->where('module', '=', $moduleId')->orderBy('created_at', 'asc');
}
Controller
$departments = tax::where([
['module', '=', $this->departmentsModuleId],
])
->whereNull('parent')
->with([
'taxChildren' => ['moduleId', '2']
])
->get();
Now , i know that i can pass a query to my relationship like so:
$departments = tax::where([
['module', '=', $this->departmentsModuleId],
])
->whereNull('parent')
->with([
'taxChildren' => function($query){
$query->where('module', '=', $this->departmentsModuleId);
},
])
->get();
but i will be using this often with multiple relations that are similar. Anyone have an idea how to achieve this? Thanks!
You can't pass argument direcly to the relationship function but this can be done with model properties
Mymodel.php
class MyModel extends Model {
protected $moduleId = null;
public function taxChildren(){
return $this->hasMany($this, 'parent')->where('module', '=', $this->moduleId)->orderBy('created_at', 'asc');
}
}
MyController.php
use App\MyModel;
...
class MyController extends Controller {
public function controllerMethod(){
$query = new MyModel;
$query->moduleId = 1;
$departments = $query::where([
['module', '=', $this->departmentsModuleId],
])
->whereNull('parent')
->with(['taxChildren'])
->get();
}
}
Also you can use laravel query scopes to set modelId property . I think that is much cleaner code
Mymodel.php
class MyModel extends Model {
protected $moduleId = null;
public function scopeMudule($q, $module_id){
$this->moduleId = $module_id;
return $q;
}
public function taxChildren(){
return $this->hasMany($this, 'parent')->where('module', '=', $this->moduleId)->orderBy('created_at', 'asc');
}
}
MyController.php
use App\MyModel;
...
class MyController extends Controller {
public function controllerMethod(){
$departments = $query::module(1)->where([
['module', '=', $this->departmentsModuleId],
])
->whereNull('parent')
->with(['taxChildren'])
->get();
}
}

Hasrole with 2 tables

I have a model named Student with the field name , here is the function, which is correct.
public function index(Request $request)
{
$user = $request->user();
$students = Student::query()
->when($user->hasRole('admin') !== true, function (Builder $query) use ($user) {
$query->where('email', $user->email);
})
->when($request->has('search'), function (Builder $query) use ($request) {
$query->where('name', 'like', '%'.$request->input('search').'%');
})
->paginate(5);
return view('admin.students.index', compact('students'))
->with('display_search', $user->hasRole('admin'));
}
Now, in my model Payment I have a request with 2 tables (Payment & Student).
Here is my function index()
public function index(Request $req)
{
if ($req->search == "") {
$payments = Payment::paginate(5);
return view('admin.payments.index', compact('payments'));
} else {
$validated = $req->validate([
'search' => 'alpha',
]);
$payments = payment::whereHas('students', function($query) use($req) {
$query->where('name', 'like', '%' . $req->search . '%');
})->paginate(5);
return view('admin.payments.index', compact('payments'));
}
}
My problem is I want to adapt my function for connect me with an user.
I have this for now ???
public function index(Request $request)
{
$user = $request->user();
$payments = Payment::query()
->when($user->hasRole('admin') !== true, function (Builder $query) use ($user) {
$query->where('email', $user->email);
})
->when($request->has('search'), function (Builder $query) use ($request) {
how to include this:
$payments = payment :: whereHas ('students', function ($ query) use ($ req) {
$query-> where ('name', 'like', '%'. $ req-> search. '%');

DB query to relationship

My query:
$data = DB::table('countries')
->leftJoin('matches', function ($join) {
$join->on('matches.hometeam', '=', 'countries.id')
->orOn('matches.awayteam', '=' ,'countries.id');
})
->where('countries.id', $id)->get();
return dd($data);
How can I get same results using relationship?
In your Model (You need a matches model aswell):
<?php
class Country extends Model {
public function matches() {
return $this->hasMany(App\Matches::class, ['hometeam', 'awayteam'], 'id');
}
}
In your controller:
$countrys = Countrys::where('id', $id)->get()
foreach($countrys as $country) {
var_dump($country->matches);
}
die();

Nested "with()" laravel

I'm having issues with some relationships. I have the following situation
Product:
public function catalogues()
{
return $this->belongsToMany('App\Catalogue');
}
public function category()
{
return $this->belongsTo('App\Category');
}
Category:
public function products()
{
return $this->hasMany('App\Product');
}
Catalogue:
public function products()
{
return $this->belongsToMany('App\Product');
}
With a single query, I need to get all the categories that have products belonging to a certain catalogue. How can I achieve it?
Use whereHas():
Category::whereHas('products.catalogues', function($q) use($catalogueId) {
$q->where('catalogues.id', $catalogueId);
})
->get();
Or:
Category::whereHas('products', function($q) use($catalogueId) {
$q->whereHas('catalogues', function($q) use($catalogueId) {
$q->where('id', $catalogueId);
})
})
->get();
You need whereHas and
Category::whereHas('products')
->with(['products' => function($query) use ($id){
$query->with('catalogues' => function($query) use ($id){
$query->where('catalogues.id',$id);
});
}])
->get();
Hope this helps.

Resources