Laravel query scope - how is $query attributes passed? - laravel

public function scopePublished($query) {
$query->where('published_at', '<=', Carbon::now());
}
How is the $query parameter passed here? Does the function pass the parameter $query to itself?
Here is the function call:
public function index() {
$articles = Article::latest('published_at')->published()->get();
return view('articles.index', compact('articles'));
}

The Model class itself passes on everything all missing method calls, except increment() and decrement(), to the underlying Query object. This is done via magic __call() and __callStatic() methods.
The Query object, \Illuminate\Database\Eloquent\Builder, then does this:
if (method_exists($this->model, $scope = 'scope'.ucfirst($method))) {
return $this->callScope($scope, $parameters);
}
I.e it checks if there is a method with the method name prefixed with scope() available on the model, and if so - it simply calls it and passing it self (i.e the Query).

Related

Laravel using where clause on Views

I'm newbie on Laravel.
I can send data like that:
public function index()
{
$InboxNew = Models\Inbox::where('read', false)->get();
$InboxMarkedAsRead = Models\Inbox::where('read', true)->get();
return view('dashboard.inbox', compact('InboxNew', 'InboxMarkedAsRead'));
}
I want to get data in view like that but gives some errors:
public function index()
{
$Inbox = Models\Inbox::all();
return view('dashboard.inbox', compact('Inbox'));
}
In view:
#if($Inbox->where('read', false)->get())
...
#endif
Your controller :
public function index()
{
$Inbox = Models\Inbox::all();
return view('dashboard.inbox', compact('Inbox'));
}
In blade you can achieve your data like this way :
#foreach($inbox as $query)
#if($query->read == false)
//
#endif
#endforeach
Problem with your code is that you have already called all() method on the Models\Inbox. What all() do is to simply call the get() method on model without applying any conditions.
You either need to define only a model (via query() method:
// Controller
public function index()
{
$Inbox = Models\Inbox::query();
return view('dashboard.inbox', compact('Inbox'));
}
and fetch it later with where clauses In view:
#if($Inbox->where('read', false)->get())
...
#endif
OR
You can do it in a cleaner way, which is to fetch the data in controller and use the view only to show the data
You either need to define only a model (via query() method:
// Controller
public function index()
{
$Inbox = Models\Inbox::where('read', false)->get();
return view('dashboard.inbox', compact('Inbox'));
}
and fetch it later with where clauses In view:
#if($Inbox)
...
#endif
PS: To check if a record exists, use exists() method instead of get() e.g $Inbox->exists()

Laravel 5.8 query scope

I am learning laravel and I encountered this problem where when I use query scope my code returns zero data. The database has got data.
It is kinda confusing because I think I have done everything right as per the tutorial
Scope:
public static function scopeLatest($query)
{
return $query->orderBy('id', 'asc')->get();
}
Controller:
public function index()
{
$posts = Post::Latest();
return view('posts.index', compact('posts'));
}
AFAIK, you won't be able to use scopeLatest as Laravel already has a latest() method on its query builder.
As for the scope you tried to make, here are a few pointers:
a scope shouldn't be defined as static method
you shouldn't actually call get() inside your scope
You don't need to return from the scope.
So even though this scope won't actually work (because of the name), as an example, this is what is would look like based on your question:
public function scopeLatest($query)
{
$query->orderBy('id', 'desc'); //desc should put the latest first
}
Your controller method (in either case) should be:
public function index()
{
$posts = Post::latest()->get();
return view('posts.index', compact('posts'));
}

Laravel error using with() method in Eloquent

I'm trying to call using with() method in Laravel Eloquent ORM, but getting the following error.
Argument 1 passed to
App\Http\Controllers\DashboardController::App\Http\Controllers\{closure}()
must be an instance of Illuminate\Database\Eloquent\Builder,
instance of Illuminate\Database\Eloquent\Relations\HasMany given
I'm using the latest version of Laravel 6. Any ideas what might have caused this?
Controller
class DashboardController extends Controller
{
public function __construct()
{
$this->middleware('auth:api');
}
public function formIndex(Request $request)
{
$id = auth()->user()->id;
$item = Groupe::find($id)->with(
[
'etudiants' => function (Builder $query) {
$query->select('id');
}
]
)->first();
return $item;
}
}
Model
class Groupe extends Authenticatable implements JWTSubject
{
public function etudiants()
{
return $this->hasMany('App\Etudiant');
}
}
The error comes from the type hint you put on the $query variable, as the error message said the object that gets passed in there is a relationship not a raw Query Builder. Just remove the type hint. Also ::find() executes a query, so you're be executing 2 queries, use the query below instead
Groupe::where('id', $id)->with(['etudiants' => function ($query) {
$query->select('id');
}])->first();
Additionally, you don't need to use the callback syntax to only eager load certain columns, the callback syntax is for putting contraints on which records get returned. Try this instead.
Groupe::where('id', $id)->with('etudiants:id,name,email')->first();
But what do you want return? groupe->students[]?? you can use
$item = Groupe::where('id',$id)->with('etudiants')->first();

How to call model in Controller request $request

I have a query in my model, which I want to call in my controller (request $request). It's working fine when the controller parameter is controller($id). But how to pass it in $request controller.
teacher Model with Query:
class teacher extends Model
{
public static function teacher($id)
{
return DB::table('teachers')
->leftjoin('religions', 'teachers.religion_id', '=', 'religions.id')
->leftjoin('areas', 'teachers.area_id', '=', 'areas.id')
->select('teachers.*','religions.*','areas.*')
->where('teachers.id',$id)
->first();
}
Controller which calls this model perfectly fine passing direct id:
public function report1($id)
{
$teacher = Teacher::teacher($id);
return View('teachers.report1' ,compact('teacher'));
}
Controller where I want to call it:
public function printreports(Request $request)
{
$teachers = $request->get('select2');
return view('teachers.report1',compact('teachers'));
}
Note: select2 contains teacher ids where I want to run model query.
Supposing you are have an array of ids in your select2 request param, probably easiest way is to change query at teacher model as follows:
use Illuminate\Support\Arr;
class teacher extends Model
{
public static function teacher($id)
{
return DB::table('teachers')
->leftjoin('religions', 'teachers.religion_id', '=', 'religions.id')
->leftjoin('areas', 'teachers.area_id', '=', 'areas.id')
->select('teachers.*','religions.*','areas.*')
->whereIn('teachers.id', Arr::wrap($id))
->get();
}
}

Pass variable from one method to another in same controller Laravel

I need to pass select option value from store method to show
i need to pass the $typeg value to show method
public function store(Request $request ) {
$typeg = $request->input('type');
}
public function show($id) {
dd($this->store($typeg));
}
i get
Undefined variable:
or
Too few arguments to function app\Http\Controllers\appController::show(), 1 passed and exactly 2 expected
Try this
on the first function you have some variable witch you want to pass it to another function\method
Than you need to use $this and the name of the other method you'd like to pass the var too something like this.
public function oneFunction(){
$variable = "this is pretty basic stuff in any language";
$this->anotherFunction($variable)
}
public function anotherFunction($variable){
dd($variable);
}
Store your data on session (or somewhere else like cookie, cache, database). So you can reach the data later.
class SomeController extends Controller {
public function store(Request $request ) {
session(["typeg"=>$request->input('type')])
}
public function show($id) {
dd(session("typeg"));
}

Resources