accessing custom method in model - laravel

Im practicing laravel and im making a custom method for my user
In my user model i have build a function like this
public function employee(){
return $this->where('user_type','employee');
}
and then in my controller I'm accessing the function like this
public function index(){
$users = User::latest()->employee();
return UserResource::collection($users);
}
but it return an error Method Illuminate\Database\Query\Builder::employee does not exist.how to fix this?

Use local scope instand
public function scopeEmployee($query)
{
return $query->where('user_type', 'employee');
}
Your controller can be as it was !
public function index(){
$users = User::latest()->employee()->get();
return ProductsResource::collection($users);
}

Related

Can I use return to a public function in controller in Laravel 8

I got an error which is undefined function.
I tried to use a public function in return:
public function CreateForm() //This the function that I want to use back
{
$names2 = DB::table('pendaftaran')
->where('isActive',0)
->orderBy('id','desc')
->get();
return view('contact')->with($variables);
}
So this a function I want to return to a function
public function AddUserSubmit(Request $request)
{
$this->validate($request,
[
'Nama'=>'required',
'NoKP'=>'required',
]);
Pendaftaran::create($request->all());
return CreateForm(); //Can I return to a public function ?
}
Yes this should work but you need to add context and use the $this keyword otherwise return CreateForm(); will be interpreted as trying to invoke a global function.
Try replacing:
return CreateForm();
With
return $this->CreateForm();
See this other question for more information: https://stackoverflow.com/a/17861505/4517964

Laravel trait crud controller with request validation and resources

I'm trying to refactor my code to be more reusable.
I created a trait CrudControllerTrait to implement the index,show,store,update,destroy methods.
But I found 2 problems:
BrandController.php
public function store(BrandNewRequest $request)
{
$requestData = $request->validated();
return new BrandResource($this->brands->store($requestData));
}
ProductController.php
public function store(ProductNewRequest $request)
{
$requestData = $request->validated();
return new ProductResource($this->products->store($requestData));
}
The trait method would be:
public function store(xxxxx $request)
{
$requestData = $request->validated();
return new xxxxxResource($this->repository()->store($requestData));
}
Problem1: The hint type. How can I abstract them? If I remove it shows that errror:
"message": "Too few arguments to function App\\Http\\Controllers\\BrandController::store(), 0 passed and exactly 1 expected"
Problem2: Return the resource. How can create the new resource? On the collection I can solve it doing this:
public function index()
{
$models = $this->repository()->index();
return $this->resource()::collection($models);
}
The resource is on the controller who uses the trait:
public function resource()
{
return BrandResource::class;
}
But with single resource didn't know how to do it...
The idea is, that I have so much controllers using the same pattern: BrandController, ProductController, etc. I'd love to reuse these 5 crud methods on the same trait...
The only way I found is creating an abstract method.
trait CrudRepositoryTrait
{
abstract function model();
public function index()
{
return $this->model()::with($this->with())->get();
}
public function find($id)
{
return $this->model()::findOrFail($id);
}
public function store($data)
{
$request = $this->dtoRequest($data);
return $this->model()::create($request);
}
(...)
}
And then, an example how to use this treat:
class ProductRepository implements ProductRepositoryContract
{
use CrudRepositoryTrait;
function model()
{
return Product::class;
}
(...)
}
By this way I could reuse a lot of code.

Laravel Nova metrics filtering

I have a model called Property which has an 'active' flag. I want a metric at the top of my resource which shows a count of active Properties.
My calculate method is exactly as in the doc but this shows all Properties rather than active ones:
public function calculate(Request $request)
{
return $this->count($request, Property::class);
}
How can I add a filter?
I've tried a where clause:
public function calculate(Request $request)
{
return $this->count($request, Property::class)->where('active','=',1);
}
And a query scope:
public function calculate(Request $request)
{
return $this->count($request, Property::class)->active();
}
I thought I might be able to use the Nova filter I set up on the resource list page but that didn't seem to work either. I'm sure it's really easy but I haven't worked it out. Thanks for your help!
Your can use every type of Eloquent\Builder instance in the $model param.
Instead of:
public function calculate(Request $request)
{
return $this->count($request, Property::class);
}
Set a Scope on your Model
App\Property.php
...
public function scopeActive($query)
{
return $query->where('active', 1);
}
public function scopeInactive($query)
{
return $query->where('active', 0);
}
And use this scope as the $model param in your calculate method, because the call of the scope returns a Eloquent\Builder Instance
public function calculate(Request $request)
{
return $this->count($request, Property::active());
// return $this->count($request, Property::inactive());
}
Edit
Of course you can make the Eloquent Builder call inline:
public function calculate(Request $request)
{
return $this->count($request, Property::where('active', 1));
}

Call to a member function diffForHumans() on null

i am getting outputs of my posts in the system but i am getting this errror Call to a member function diffForHumans() on null... Can u please help me? Thanks...
Article model is that:
protected $fillable=[
'user_id','content','live','post_on'
];
public function setLiveAttribute($value)
{
$this->attributes['live']=(boolean)($value);
}
And the articlescontroller is that
public function index()
{
$articles = Article::all();
return view('articles.index', compact('articles'));
}
public function create()
{
return view('articles.create');
}
public function store(Request $request)
{
Article::create($request->all());
}
public function show()
{
}
public function update()
{
}
public function destroy()
{
}
The problem is for sure not here. You probably try to run diffForHumans() in your view for example like this:
$user->post_on->diffForHumans()
but post_on is set to null instead of date.
So you should verify where exactly you run this method, set this column as date and in your view add something like this:
Posted: {{ $date ? $date->diffForHumans: '-' }}

conbine response return and view

I have two return in my controller method.
How can I combine both?
public function index()
{
$data=Event::get(['title','start','color']);
$objectifs=Objectif::all();
$ob=Array('objectifs'=>$objectifs);
return view('newc')->with('objectifs', $objectifs);
return Response()->json($data);}
we can't use 'return' multiple times
public function index() {
$data = Event::pluck('title', 'start','color' );
return Response()->json($data);
}
use another controller function
public function jason() {
$ob=Array('objectifs'=>$objectifs);
return view('newc')->with(compact('ob'));
}
You should read this laravel docmentaion
https://laravel.com/docs/5.2
In place of using two return you can use multiple "with" like this
public function index()
{
$data=Event::get(['title','start','color']);
$objectifs=Objectif::all();
$ob=Array('objectifs'=>$objectifs);
return view('newc')->with('objectifs', $objectifs)->with('data',$data);

Resources