Category slug + post slug Laravel Eloquent - laravel

I have a blog route and I'd like to show article with a category_slug.
Route::get('/blog/{category_slug}/{slug}', [App\Http\Controllers\BlogController::class, 'index'])
->where('category_slug', '[\-_A-Za-z]+')
->where('slug', '[\-_A-Za-z]+');
public function categories_blog()
{
return $this->belongsTo(CategoriesBlog::class, 'category_id');
}
public function blogs()
{
return $this->hasMany(Blog::class);
}
with this eloquent relations works fine:
example: www.mysite.com/blog/first_article
public function index($category_slug, $slug)
{
$blogs = Blog::with('categories_blog')
->where('slug', '=', $slug)
->first();
}
with this eloquent relations doesn't work:
example: www.mysite.com/blog/accessories/first_article
public function index($category_slug, $slug)
{
$blogs = Blog::with('categories_blog')
->where('category_slug', '=', $category_slug)
->where('slug', '=', $slug)
->first();
}
Doesn't recognize relationship with 'categories blogs':
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'category_slug' in 'where clause' (SQL: select * from `blogs` where `category_slug` = accessories `slug` = first_article limit 1)
How I can fix it or is there is a best way for get this?
thank you very much.

Use whereHas
$blogs = Blog::with('categories_blog')->whereHas('categories_blog',function ($query)use($category_slug){
$query ->where('category_slug', $category_slug);
})
->where('slug',$slug)
->first();

Related

Laravel call relation from model in when() conditional clauses

I am creating product filtering and now I have problem when I want to filter product category by name.
I am not sure if is possible to call relation inside when() conditional clauses.
In the product controller, I create:
$results = Product::query();
// Conditional filter
$results->when($request->has('product_code'), function ($q) use ($request) {
return $q->where('product_code', 'like', '%'.$request->query('product_code').'%');
});
$results->when($request->has('status'), function ($q) use ($request) {
return $q->where('status', $request->query('status'));
});
$results->when($request->has('price'), function ($q) use ($request) {
return $q->where('price', $request->query('price'));
});
// Filter by category NAME
// HERE IS PROBLEM
$results->when($request->has('category_name'), function ($q) use ($request) {
return $q->category->where('name', $request->query('cat_name'));
});
// I also try
// This return SQLSTATE[42S22]: Column not found: 1054 Unknown column 'category.name' in 'where clause' (SQL: select count(*) as aggregate from `products` where `category`.`name` = Apple)
$results->when($request->has('category_name'), function ($q) use ($request) {
return $q->where('category.name', $request->query('cat_name'));
});
$results = $results->paginate(20);
Model:
class Product
{
public function category()
{
return $this->hasOne('App\Models\Category', 'id', 'category_id');
}
}
for this filtering do this:
$filter = [];
if($request->product_code!= null)
array_push($filter, ['product_code', 'like', "%$request->product_code%"]);
if($request->price)
array_push($filter, ['price', $request->price]);
// and so on ...
then you have array of conditions, just call where and pass the array:
$results = Product::where($filter);
How about that?
$category_ids = Category::where('category_name', $request->query('category_name'))->pluck('id');
$results = Product::select("*")->when($request->has('category_name'), function ($query) use ($request, $category_ids) {
return $query->whereIntegerInRaw('category_id', $category_ids);
})->get();

How to filter by date in Eloquent relationship

I've two tables first_levels and second_levels the first_levels have a relationship with themselves as parent and child and in the second table, I store the transactions.
my Model:
public function children()
{
return $this->hasMany(first_level::class, 'parent_id', 'Nominal')
->with(['children', 'transactions'])
->withsum('transactions', 'debit')
->withsum('transactions', 'credit');
}
public function transactions()
{
return $this->hasMany(second_level::class, 'first_level_id', 'id');
}
my controller:
function getGeneralLedger(Request $request)
{
$items = first_level::with('children')
->where('parent_id', 0)
->where('company_id', $request->user()->company_id)
->get();
return response()->json(['data' => $items]);
}
using this model and controller I can get all the data from the first and second tables but when I want to filter the second table based on the created_at column I'm unable to do it.
I tried this method but it didn't work.
function getGeneralLedger(Request $request)
{
$items = first_level::with('children')
->where('parent_id', 0)
->where('company_id', $request->user()->company_id)
->wherebetween('children.transactions.created_at', [$request->from, $request->to])
->get();
return response()->json(['data' => $items]);
}
I get this error
Column not found: 1054 Unknown column 'children.transactions.created_at' in 'where clause' (SQL: select * from `first_levels` where `parent_id` = 0 and `company_id` = 1 and `children`.`transactions`.`created_at` between 2022-01-10 and 2022-02-09)",
try
function getGeneralLedger(Request $request)
{
$items = first_level::with('children')
->where('parent_id', 0)
->where('company_id', $request->user()->company_id)
->whereHas('children.transactions', function ($q) use ($request) {
$q->wherebetween('created_at', [$request->from, $request->to]);
})
->get();
return response()->json(['data' => $items]);
}
Source: https://laravel.com/docs/8.x/eloquent-relationships#querying-relationship-existence

SQLSTATE 42S22 Column not found

I know that I don't have the table in phpmyadmin
but the problem is I don't know how to do it the right way
The code
public function DriverRefer($id)
{
$driver = Driver::find($id);
$query = ReferralDiscount::where([['referral_driver_id', '=', $id], ['referral_sender_id', '!=', 0]])->latest();
$referral_details = $query->paginate(25);
return view('merchant.driver.driver_refer', compact('referral_details', 'driver'));
}
Illuminate \ Database \ QueryException (42S22)
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'referral_driver_id' in 'where clause' (SQL: select count(*) as aggregate from referral_discounts where (referral_driver_id = 4130 and referral_sender_id != 0))
Previous exceptions
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'referral_driver_id' in 'where clause' (42S22)
I added a model inside App/Models named DriverReferralDiscount:
<?php
class DriverReferralDiscount extends Model
{
protected $guarded = [];
public function Driver()
{
return $this->belongsTo(Driver::class, 'referral_driver_id');
}
public function SenderDriver()
{
return $this->belongsTo(Driver::class, 'referral_sender_id');
}
public function getSenderDetails($driver_id)
{
$refer = ReferralDiscount::where([['referral_driver_id', '=', $driver_id], ['referral_sender_id', '!=', 0]])->get();
return $refer;
}
public function getSenderCount($driver_id)
{
$refer = ReferralDiscount::where([['referral_driver_id', '=', $driver_id], ['referral_sender_id', '!=', 0]])->count();
return $refer;
}}
And changed the code to
public function DriverRefer($id){
$driver = Driver::find($id);
$query = DriverReferralDiscount::where([['referral_driver_id', '=', $id], ['referral_sender_id', '!=', 0]])->latest();
$referral_details = $query->paginate(25);
return view('merchant.driver.driver_refer', compact('referral_details', 'driver'));}
Then i added a table in phpmyadmin named driver_referral_discounts with columns:
id
referral_driver_id
referral_sender_id
referral_offer
referral_offer_value
referral_available
created_at
updated_at
Really sorry if it's not clear but i tried as best as i could in case this would help anyone else.

How to use where() for column that belong to with()

I'm working with Laravel framework.
I want to get the data for promotion with the certain category.
<b>Table</b><br>
product<br>
------<br>
id<br>
name<br>
price<br>
promotion<br>
----------<br>
id<br>
product_id<br>
discount<br>
category<br>
---------<br>
id<br>
name<br>
product_category<br>
----------------<br>
product_id<br>
category_id<br>
$promotions = Promotion::with('product')->with('category')
->whereIn('category_id', ['1','2'])
->paginate(9);
Promotion model - connect relation for product and category
// relationship with product
public function product()
{
return $this->belongsTo('App\Model\Product');
}
//relationship with category
public function category()
{
return $this->belongsToMany('App\Model\Category', 'products_categories', 'product_id', 'category_id');
}
Error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'category.id' in 'where clause' (SQL: select count(*) as aggregate from promotions where category.id in (1, 2))
Try this:
$promotions = Promotion::with('product.category')
->whereIn('category_id', ['1','2'])
->paginate(9);
Assuming that you have to create the correct relations in models.
Edit:
In the Promotion Model :
// relationship with product
public function product()
{
return $this->belongsTo('App\Model\Product');
}
and the Product Model:
//relationship with category
public function product_category()
{
return $this->belongsTo('App\Model\ProductCategory', 'product_id', 'id');
}
In the Category Model:
//relationship with category
public function product_category()
{
return $this->belongsToMany('App\Model\ProductCategory', 'category_id', 'id');
}
So the query like:
$promotions = Promotion::with('product.product_category')
->whereIn('category_id', ['1','2'])
->paginate(9)
How about :
$promotions = Promotion::with([ 'product.category' => function($q){
return $->whereIn('category_id', ['1','2']);
}])
->paginate(9);
If you want to get all promotions which have a category having id in 1,2 you can do :
$promotions = Promotion::whereHas('product.category' => function($q){
return $->whereIn('category_id', ['1','2']);
})
->paginate(9);
This will just get you promotions and not the categories. if thats what you were looking for.
You can simply use this:
$promotions = Promotion::whereHas(
'product.category',
function ($q) {
$q->whereIn('category_id', ['1', '2']);
})
->paginate(9);

Eloquent - how to add a join in the hasMany relationship?

I have a typical hasMany method:
public function earmarks() {
return $this->hasMany('App\Earmark');
}
But how do I add a join and some other conditions to this relationship when I use the ->with('earmarks') to retrieve them? I want to add:
->join('locations', 'locations.id', '=', 'earmarks.location')
->select('earmarks.*', 'locations.location AS em_location')
->orderBy('date', 'asc');
OK, figured out I need a closure in my with() clause, like this:
$updated_laptops = Laptop::with([
'earmarks' => function($q) {
$q
->join('locations', 'locations.id', '=', 'earmarks.location')
->select('earmarks.*', 'locations.location AS em_location')
->orderBy('date', 'asc');
}
])->addJoins()->selectListCols()->find($request->IDs)->keyBy('id');
this worked for me
public function earmarks() {
return $this->hasMany('App\Earmark', 'labtop_id', 'id')
->join('locations', 'locations.id', '=', 'earmarks.location')
->select('earmarks.*', 'locations.location AS em_location')
->orderBy('date', 'asc')->get();
}
it can be a attribute in Labtop Model and be serializable in Labtop json object like this :
public function GetEarmarksAttribute() {
return $this->hasMany('App\Earmark', 'labtop_id', 'id')
->join('locations', 'locations.id', '=', 'earmarks.location')
->select('earmarks.*', 'locations.location AS em_location')
->orderBy('date', 'asc')->get();
}
protected $appends = array('earmarks');
When you defined a hasMany method in the Location model (e.g. \App\Models\Location.php)
public function earmarks() {
return $this->hasMany('App\Earmark');
}
You can return a Location object in Controller (e.g. LocationController.php ):
public function show($id)
{
$location = \App\Models\Location::find($id);
return view('locations.show)
->with('location', $location);
}
Then in the view (e.g. locations\show.blade.php), you can retrieve the data like this:
#foreach ($location->earmarks->sortBy('date') as $earmark )
<p>{{ $earmark->attribute_name }}</p>
#endforeach

Resources