how to send variable from controller to model function in laravel - laravel

I want to send variable $typeid to function categories to use it in query is there a way Knowing that when I try to use new instance of class in my controller like that:
$cat= new Main_category();
$categories = $cat->categories()->get();
it returns empty array
the following code is working well when I manually add the typeid inside the model function I want to have it as a variable sent from controller
controller:
$categories = Main_category::with('categories')->get();
Model
public function categories()//($typeid)
{
$query = $this->hasMany(Category::class, 'main_cat_id')
->join('category_type','category_type.cat_id','=', 'categories.cat_id')
->join('main_categories','main_categories.main_cat_id','=', 'categories.main_cat_id')
->where('category_type.type_id', '1'); // I want to use $typeid here
return $query;
}

I am not sure whether you can pass your variable in eloquent relationship methods by using with method or not. But you can add a where clause in controller.
Main_category::with(['categories' => function($query) use($typeid) {
$query->where('category_type.type_id', $typeid);
}])->get();
Or you can create a query scope for model too.
in Model
public function scopeWithCategories($query, $typeid) {
return $query->with(['categories' => function($query) use($typeid) {
$query->where('category_type.type_id', $typeid);
}]);
}
and finally in Controller
Main_category::withCategories($typeid)->get();

Related

How to use custom model function in eloquent

I want to get all user's online friends, how can I call a custom model function inside the eloquent condition?
this is my code
$friends = $user->friends()->where(function (Builder $query){
$query->where('friend', 'yes');
})
->get();
and this is my function in model
public function getIsOnlineAttribute(): bool
{
// check if the user is online or not
return $this->is_online;
}
I can access is_online after eloquent by foreach, but in my case, I want to check everything in one step ( inside where condition in eloquent). how can I do that???
You can't use conditions for eloquent accessors, in this case you can use (assume 1 is database column value):
$friends = $user->friends()->where('is_online', 1)->get();
or
$friends = $user->friends()->whereIsOnline(1)->get();
or you can create eloquent scope on your model:
public function scopeIsOnline($query) {
$query->where('is_online',1);
}
and you can use this eloquent scope on your controller in this way:
$friends = $user->friends()->isOnline()->get();
this worked for me :)
$friends = $user->friends()
->simplePaginate()
->reject(function ($friend) {
return $friend->is_online === false;
});

Call function from model by passing a variable

I am approaching Laravel 7, and I am lost in a banality I guess. I create a function in the model that picks up the count of how many posts a category has, then passing the ID parameter.
I call this function in the controller, which then picks up the variable in the views.
It gives me an error:
Object of class Illuminate\Database\Eloquent\Builder could not be
converted to string
How can I solve it?
MODEL
public function scopeCountActivePostCategory($id)
{
$query = DB::table('post')->where([
['status', 1],
['category', $id],
]);
return $query->count();
}
CONTROLLER
// get details category by slug
// preleva dettagli categoria by slug
$detailCat = DB::table('categories')->where('slug', $slug)->first();
// get stories
$post = DB::table('post')
->orderByDesc('id')
->where('category', $detailCat->id)
->where('status', 1)
->paginate($set->app_result_x_page);
return view('category')->with([
'posts' => $posts,
'set' => $set,
'totalActivePost' => Post::CountActivePostCategory($detailCat->id),
'detailCat' => $detailCat
]);
You're missing a get() in your query. The way you have it, you're trying to count query builder (SQL query string) instead of the collection you would get by putting get() on the end of your builder. Change your code to this:
public function scopeCountActivePostCategory($id)
{
$query = DB::table('post')->where([
['status', 1],
['category', $id],
])->get(); //Get here
return $query->count();
}
EDIT
The calling of CountActivePostCategory function might be a problem as well. You are calling static function CountActivePostCategory but you didn't define it as static in your Post model. Change your function to this:
public static function countActivePostCategory($id){
//body
}
And then call it in your controller like this:
'totalActivePost' => Post::countActivePostCategory($detailCat->id)

Laravel Eloquent get all categories of restaurants?

I'm trying to get all categories of restaurants.
My models:
Restaurant
public function categories()
{
return $this->belongsToMany(Category::class,'restaurant_categories_relation','restaurant_id');
}
Category
public function restaurants()
{
return $this->belongsToMany(Restaurant::class,'restaurant_categories_relation', 'category_id');
}
In my controller:
$restaurants = Restaurant::where('district_id', $request->district)->paginate(8);
$categories = $restaurants-> ????;
Please help me do this, thanks!
You could use has() like :
Category::has('restaurants')->get();
That will return the categories who are related with the restaurants.
Try also the use of whereHas like :
$users = Category::whereHas('restaurants', function($q){
$q->->where('district_id', $request->district)->paginate(8);
})->get();
Since you've already a Collection we can't query the categories so I suggest adding a function to scope that inside the Restaurant model like :
public static function getCategoriesOfRestaurants($restaurants)
$categories = [];
foreach($restaurants as $restaurant){
array_push( $categories, $restaurant->categories->pluck('id')->toArray());
}
return Category::WhereIn('id', array_unique($categories))->get();
}
Then just call it when you get the $restaurants collection :
$restaurants = Restaurant::with("categories")->where('district_id', $request->district)->paginate(8);
$categories = Restaurant::getCategoriesOfRestaurants($restaurants);
Note: The use of with("categories") when getting the collection will query All the related categories in the first query so the foreach loop will not generate any extra query just looping through the already fetched data, and finally we will get the collection of categories in the return statement.
use with() method for eagerloading, that provides you get all categories in a single query
$restaurants = Restaurant::with("categories")->where('district_id', $request->district)->paginate(8);
foreach($restaurants as $restaurant){
foreach($restaurant->categories as $category)
{{$category}}
}
}
if you want to use categories outside of the loop, then assign these categories to a variable
foreach($restaurants as $restaurant){
$categories = $restaurant->categories;
}
// do something with $categories
Your relation should be
Restruant.php
public function categories() {
return $this->belongsToMany(Category::class,'restaurant_categories_relation','restaurant_id','category_id');
}
then in you controller method just wirte
$restruants = Restruant::with('categories')->get();
It should return you collection of all restruants with all related categories.

How to execute laravel WHERE along with EloquentFilter

I am using this EloquentFilter to filter Database on the frontend and the controller below works
public function indexArtisan(Request $request)
{
$workers = Worker::filter($request->all())->get();
$states = DB::table('states')->pluck("name", "id");
return view ('artisans', compact('states'))->with(['workers' => $workers]);
}
However, when i try to use the WHERE query to add conditions to the data been called with the controller, the WHERE condition is met and data returned but my filter no longer works. domain.com?name=xyz
public function indexArtisan(Request $request)
{
$work = DB::table('workers')->where('career', '=', 'artisan')->get();
$workers = Worker::filter($request->all())->get();
$states = DB::table('states')->pluck("name", "id");
return view ('artisans', compact('states','work'))->with(['workers' => $workers]);
}
Also tried
$work = DB::table('workers')->where('career', '=', 'artisan')->get();
$worker = $work->filter($request->all());
$states = DB::table('states')->pluck("name", "id");
return view ('artisans', compact('states'))->with(['worker' => $worker]);
I get
How do i execute the WHERE condition without breaking the filter
I've read https://laravel.com/docs/5.6/queries#conditional-clauses i still cant figure out what i'm doing wrong.
If you use $work->filter($request->all()); the filter() method is the method of collection class, because $work is a collection now.
So, you need to use filter() method of model class
DB::table('workers')->where('career', 'artisan')->filter($request->all())->get();
should work.

How to add condition in connection tables?

I have two tables: Users and Images.
So, a user can have some images.
For this relationship I have additional function in model User:
public function images()
{
return $this->hasMany('App\Images', 'idElement', 'id');
}
And in controller I have:
$users = Users::where('id', $id)->with("images")->get();
How can I add additional condition in controller for images table that will be "where images.type = 1"?
Now this tables are connected only by primary keys, but I need to set a new condition yet.
You can filter your images with callback function, try this:
$users = Users::where('id', $id)->with(["images" => function ($query){
$query->where('type', 1);
}])->get();
For something like this, where you want to scope down a subset of images based on their type, you can add another method called something like public function scopedImages() and define it as such:
public function scopedImages() {
return $this->hasMany('App\Images', 'idElement', 'id')->where("images.type", "=", 1);
}
In your controller, you would access this function the same as you would the images() function on User:
$users = Users::where('id', $id)->with(["scopedImages"])->get();
Keep the function images() as well, so if you need to find all images attached to a User, but adding additional functions like this gives you flexibility on what you want to return and when.

Resources