Property [columns] does not exist on the Eloquent builder instance - laravel

i'm getting this error while trying to add a subquery select to a query builder. this error occurs when i try to get the product count for a given category.
addSubSelect Macro
Builder::macro('addSubSelect', function ($column, $query) {
if (is_null($this->columns)) {
$this->select($this->from.'.*');
}
return $this->selectSub($query, $column);
});
Category.php
public function scopeWithProductCount($query){
$query->addSubSelect('products_count', function($query) {
$query->whereHas('product', function ($query) {
$query->select('id')
->from('products')
->whereColumn('category_id', 'category.id')
->count();
});
});
}
Category Controller
public function index()
{
$categories = $this->user()->store->categories()
->withProductsSum()
->get();
return response()->json($categories);
}
i changed the scopedWithProductCount method to this to try and get more debugging options but i end up with the same error
public function scopeWithProductCount($query){
$query->addSubSelect('', function($query) {
});
}

The columns property is in the Illuminate\Database\Query\Builder Class and not Illuminate\Database\Eloquent\Builder. Your $this will refer to the Eloquent\Builder reference and not the Query\Builder.
So try changing your macro like this:
addSubSelect Macro
Builder::macro('addSubSelect', function ($column, $query) {
if (is_null($this->getQuery()->columns)) {
$this->select($this->from.'.*');
}
return $this->selectSub($query, $column);
});

Write join and the name of the table before the field:
public function scopeWithProductCount($query){
$query->addSubSelect('products_count', function($query) {
$query->whereHas('product', function ($query) {
$query->select('products.id')
->from('products')
->join('categories', 'categories.id', '=', 'products.category_id')
->count();
});
});
}

Related

Laravel pass value from query to with() function

Here is my query:
$fix = Fixture::select('fixtures.*')
->whereDate('kickoff', '<', $date)
->with('competition')
->with('teamA')
->with(['teamA.standing' => function ($q) {
$q->whereColumn('standings.competition_id', '=', {{here i want the competition_id from competitions or fixtures table}} );
}])
->with('teamB')
->with(['teamB.standing' => function ($q) {
$q->whereColumn('standings.competition_id', '=', {{here i want the competition_id from competitions table or fixtures table}});
}])->get();
Code from Fixture model:
public function teamA()
{
return $this->belongsTo(Team::class,'team_a','id');;
}
public function teamB()
{
return $this->belongsTo(Team::class,'team_b','id');;
}
Code from Team model:
public function standing()
{
return $this->hasOne(Standing::class);;
}
Code from Standing model:
public function team(){
return $this->belongsTo(Team::class);
}
public function competition()
{
return $this->belongsTo(Competition::class);
}
Can someone help me to get this done or if I am doing it wrong what's the correct way?
->with(['teamA.standing' => function ($q) {
$q->whereColumn('standings.competition_id', '=', {{here i want the competition_id from competition table or fixtures table}} );
}])
Example:
Category::select('id', 'name')->whereHas('statuses', function($query) { $query(); })->with('courses')->get();

How to show Laravel model with belongsToMany connection if has specified connection?

I have this product model:
public function categories() {
return $this->belongsToMany('App\Category', 'product_categories');
}
And in my controller:
public function search(Request $request) {
return Product::with([
'categories' => function($categories) use ($request) {
// ...
}
]);
}
If I try to use $request in the categories function it's search only in categories, but shows all products.
How do I show only that products whitch has defined categories in $request->category_id?
you may use the whereHas keyword in laravel:
public function search(Request $request) {
return Product::with('categories')
->whereHas('categories', function ($query) use ($request){
$query->where('category_id', $request->category_id);
})->get();
}
Here is the docs
You can search it in following way:
public function search(Request $request) {
return Product::with('categories')
->whereHas('categories', function ($q) use (request) {
$q->where('id', $request->category_id);
});
}

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

Relationships in Laravel Models

How can I write this without a join for a scope in a Laravel model as the 'id' field becomes ambiguous
/**
* Return events that social category name
*/
public function scopeWithSocialEvents($query)
{
return $query->join('categories', 'events.event_type_id', '=', 'categories.id')
->where('categories.name', 'social');
}
Use this:
public function eventType()
{
return $this->belongsTo(Category::class);
}
public function scopeWithSocialEvents($query)
{
return $query->whereHas('eventType', function($query) {
$query->where('name', 'social');
});
}

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