Set a eager loading function in my eloquent Object - php

To avoid duplicate code, I would like to create a function eagerLoading() in my eloquent model. Here is my code:
Model Product:
public function scopeActive($query)
{
return $query->where('active', 1);
}
public function eagerLoading($query)
{
return $query->with([
'owners',
'attributes',
'prices' => function ($query)
{
$query->orderBy('created_at', 'desc');
$query->distinct('type');
}
]);
}
MyController:
$products = Product::active()->eagerLoading()->paginate(100);
return $this->response->withPaginator($products, $this->productTransformer);
But when using this, I have this error : Call to undefined method Illuminate\Database\Query\Builder::eagerLoading().
How should I use my function?

Your eagerLoading() method is just another scope, like your scopeActive() method. In order to do what you want, you need to rename it to scopeEagerLoading().
Right now, Product::active() is returning an Eloquent Query Builder. You are then trying to call eagerLoading() on that, and the method doesn't exist. By prefixing the method with scope, it tells the query builder to call the method on the Model for which it is querying.

From the documentation:
"To define a scope, simply prefix an Eloquent model method with scope."
Check documentation at: https://laravel.com/docs/5.1/eloquent#query-scopes
So you need to rename your method to have "scope" at the beginning.
Change public function eagerLoading($query) to be public function scopeEagerLoading($query)

Related

Call controller function in another controller

I've a PermissionController with a permission() function like below, and i want to call the permission() function in another controller. How can i call my permission() function to another controller ?
here my PermissionController
class PermissionController extends Controller
{
public function permission(){
$checkPermission = User::leftJoin('employees', 'employees.user_id', '=', 'users.id')
->leftJoin('positions', 'employees.position_id', '=', 'positions.id')
->leftJoin('divisions', 'employees.division_id', '=', 'divisions.id')
->where(function($query){
$query->where('division_name', 'Sales')
->orWhere('division_name', '=', 'Project Management')
->orWhere('position_name', '=', 'Dept Head');
})
->get();
}
}
Create new Helper (e.g PermissionHelper.php) then move the funtion to it and call it where you want using :
PermissionHelper::permission();
Hope this helps.
You can call another controller's method, but this is terrible practice. Move you code to a model and call it with:
class PermissionController extends Controller
{
public function permission()
{
$checkPermission = User::getEmployeePermissions();
}
}
Do the same in other controllers' methods.
I think your function should be in one of your model since you're only getting value.
This will me more relevant according to MVC.
Having it in your User model will let you use it on every instance of your application with a single call.
You can call your PermissionController's "permission" method this way :
app(PermissionController::class)->permission();
However, be aware that this method isn't a good idea at all.
You have multiple refactoring options available ranging from the use of a helper class, a method on the concerned model or using a laravel job.
Try to do like this
public function __construct(PermissionController $permission_controller)
{
parent::__construct();
$this->permission_controller = $permission_controller;
}
Call any method like this
$this->permission_controller->permission();

Laravel Eloquent: How do I refactor this eager load query into model scope method?

I have a Card model which has many notes. And each note has an author. I am eager loading an individual card in a show action in my CardsController like so:
$card = $card->load(['notes' => function($query){
$query->orderBy('created_at', 'desc')->limit(8);
}, 'notes.author']);
This query works. I want to now refactor this into a model scope so I can just call $card = Card::popular() in my controller. So add this method to my Card model:
public function scopePopular()
{
$results = $this->with(['notes' => function($query){
$query->orderBy('created_at', 'desc')->limit(8);
}, 'notes.author']);
return $results;
}
This messes up everything. I start getting unreadable template errors, when nothing should really break.
What am I doing wrong?
In order to use it as a static function and still be able to access the static methods within the class, use self:: instead of $this->.
public function scopePopular()
{
$results = self::with(['notes' => function($query){
$query->orderBy('created_at', 'desc')->limit(8);
}, 'notes.author']);
return $results;
}

Laravel query builder chaining

I want to define blocks of query builder within my model:
So it's cunctions might be used like this:
class Transactions extends Eloquent {
public function dateRange($from,$to){
return $this->whereBetween('date', [$from,$to]);
}
public function category($categ){
return $this->where(['categ' => $categ]);
}
...etc , more query block functions
}
so I could chain ans reuse these, like so:
$t = new Transactions();
dd($t->category($cat)->dateRange()->get())
or as i desire ...
$t2 = new Transactions();
dd($t2->dateRange()->get())
This (first example of usage) will thow A Call to undefined method Illuminate\Database\Query\Builder::dateRange()
p.s. second example works, but i need to chain more than one of Qblocks to my model instance...
Try to change your code like this:
class Transactions extends Eloquent {
public function scopeDateRange($query, $from, $to){
return $query->whereBetween('date', [$from, $to]);
}
public function scopeCategory($query, $categ){
return $query->where(['categ' => $categ]);
}
}
You should take a look at the query scope documentation of Eloquent : http://laravel.com/docs/5.0/eloquent#query-scopes.

Yii2: Use scopes of realtion in with() of ActiveRecord

In Yii1 I could do something like this:
$posts=Post::model()->with(array(
'comments'=>array(
'scopes'=>array('recently','approved')
),
))->findAll();
Is there a way to call a scope of a relation in the callback function of with() in Yii2?
Customer::find()->with([
'orders' => function ($query) {
$query->andWhere('status = 1');
},
'country',
])->all();
A clean solution is by overriding the model's find() method to use a custom ActiveQuery class :
class Order extends yii\db\ActiveRecord
{
public static function find()
{
return new OrderQuery(get_called_class());
}
}
class OrderQuery extends yii\db\ActiveQuery
{
public function payed()
{
return $this->andWhere(['status' => 1]);
}
}
then you can use it like :
$customers = Customer::find()->with([
'orders' => function($q) {
$q->payed();
}
])->all();
You can also chain many of them like Yii 1 scopes.
In this post you'll find more examples on how to use ActiveQuery class to build Named Scopes :
Yii2 : ActiveQuery Example and what is the reason to generate ActiveQuery class separately in Gii?

Laravel 4 passing database query from model to controller - error call to member function on non-object

Confused about why this isn't working, trying to pass a database query function to my controller. I am receiving the error Call to a member function getCompanyData() on a non-object
Review.php (Model)
class Review extends Eloquent {
public function getCompanyData($company)
{
return $this->select('head', 'body', 'logo', 'name')
->where('company', '=', $company)
->firstOrFail();
}
}
ReviewController.php
class ReviewController extends BaseController {
protected $review;
public function __construct(Review $review)
{
$this->beforeFilter('csrf', array('on' => 'post'));
$this->review = $review;
}
public function show($company)
{
$data = $this->review->getCompanyData($company);
return View::make('reviews.show', compact('data'));
}
}
I'm not sure about the problem but since you mentioned you want be able to call Review::method() but don't want to declare the method as static, so, in this case, it's possible to call using static :: syntax a non-static method declared in an Eloquent Model in Laravel using scope like this:
class Review extends Eloquent {
public function scopeGetCompanyData($query, $company)
{
return $query->select('head', 'body', 'logo', 'name')
->where('company', '=', $company);
}
}
Now you can call the getCompanyData method from your controller like this way:
$data = Review::getCompanyData($company)->firstOrFail();
So review is not an object, and you are trying to call its method like it is object. It is probably array. I see you provided Request $request reference and you expect it to be and object. It sometimes happens to me while passing values to view. Try to track type of review.
Update:
Some other things to consider are: Why did you pass Review through constructor, when it is model that extends Eloquent and it should be visible ? Does Review really extends Eloquent ?

Categories