I am trying to autoload models in laravel 9,
I want to use models in my blade files, but when i use a model i have to import it writing "use App\Models\User", and after i can write "{{ User::all() }}", but if i dont import the model first it gives me this error: "Class "User" not found", so i want to write "{{ User::all() }}" without importing the model first (without writing this: "use App\Models\User") in the blade file. How can i autoload them?
You can manually alias things in config/app.php.
'aliases' => Facade::defaultAliases()->merge([
'User' => App\Models\User::class,
... your other models here
])->toArray(),
This will make User available without having to manually write App\Models\User every time in the view and everywhere else.
Just like you can write
use DB;
DB::table('users')->get();
instead of
use Illuminate\Support\Facades\DB;
DB::table('users')->get();
You will be able to write use User instead of use App\Models\User (though I do not recommend you to do this).
Just like you do in all other Laravel versions, for example:
$query = User::with("posts");
$users = $query->get();
Where User class needs to define what "posts" means, like:
use \App\Post;
// ...
public function posts()
{
return $this->hasMany(Post::class, 'user_id');
}
Note that above I query the "User" model, and auto-load any related "Post" model.
Related
In Laravel 7 fetching a model was pretty straightforward, i just needed to setup mi resource route and make a get to the address:
http://localhost/test/public/employee/1
But i cant make it work on Laravel 8, according to my understanding i just need to do this:
public function show(Employee $employee)
{
dd($employee);
}
But dd only returns an empty class:
If i do this:
public function show(Employee $employee)
{
dd(Employee::find(1));
}
dd returns the correct data:
Route::resources([
'employee' => EmployeeController::class,
]);
Can somebody help me find what am i missing?
Regards...
Route::resource('employee', EmployeeController::class);
https://laravel.com/docs/8.x/controllers#resource-controllers
Your Route must have the same variable like
Route::get('/employee/{employee}', 'EmployeeController#show');
And ensure you have binding middleware enabled for this route. ->middleware(['bindings']);
Updating for Resource routing:
Route::resource('/employee', 'EmployeeController')->middleware('bindings');
The problem was that i was naming the routes in spanish:
Route::apiResource('empleados', EmployeeController::class);
And because of this Laravel is expecting to receive the model encapsulated in a spanish verb class (empleados instead of employee), So i needed to rename the parameter inside the method controllers to receive the correct model:
public function show(Employee $empleado)
{
return $empleado;
}
I'm just playing around with my code and notice that one of my controller is returning empty attributes but the other is returning my data fine.
I have two controllers, OneController and TwoController with both resource and same model in it. I use the php artisan make:controller OneController --model==MyModel
and php artisan make:controller TwoController --model==MyModel. two different controller with similar model.
Both have
public function show(MyModel $myModel)
{
dd($myModel);
}
But only theOneController#show is returning my data...
My links are like this
{{route('one.show', $myModel->id) }}
and
{{route('two.show', $myModel->id) }}
I also run php artisan route:clear
I change my TwoController#show to show($id) and it is working fine but I can't ignore that the same code is giving me different results and I want my code to be as clean as possible.
Is there any rule in Laravel 5.8 that you can only use One controller per model on a resource?
Am I missing something?
Thanks!
You're injecting the model you want into your controller action, instead of fetching the record yourself using the ID parameter. Because you're using this you need to adhere to certain rules - read the route model binding documentation for more information.
Long story short: the name of the parameter in the route definition and the name of the argument in the controller action need to match in order for route model binding to take place - otherwise a new model instance will be passed to the method.
Because you're using the Route::resource() method instead of defining routes yourself Laravel will automatically call the parameter by the path you pass in. You can verify this by running php artisan route:list.
To achieve this with a resource you'll need to manually name the resource parameters, which would effectively be something like Route::resource('two', 'TwoController')->parameters(['two' => 'myModel']) where myModel would be your model name.
I am working on a Laravel 5.5 application. When I use php artisan make:model SomeModel -mr it creates the model, migration and resource controller.
I've been noticed that some methods have by default only one parameter: the model:
public function show(SomeModel $someModel)
{
...
}
If you look into the $someModel variable it has an empty SomeModel object.
I was reading on Laravel Documentation that it looks like the Containers or Facades but I am not sure how to use this. Do you?
Edit 1:
I had my routes defined in routes/web.php as: Route::resource('users', 'UserController');
Now I had to define all the routes manually since automatic binding was not working:
Route::get('users', 'UserController#index');
Route::get('users/create', 'UserController#create');
Route::post('users', 'UserController#store');
Route::get('users/{user}/edit', 'UserController#edit', function(App\User $user) {});
Route::post('users/{user}', 'UserController#update', function(App\User $user) {});
Route::post('users/{user}/delete', 'UserController#destroy', function(App\User $user) {});
So, should I replace every resource controller route to manual routing like this?
The resource controller is expecting you to use route model binding. In your routes file, each route that corresponds to a controller action with an injected model will need to have a matching parameter.
For example:
Route::get('user/{user}', 'UserController#show');
Using the above route, the following controller action would receive a user instances that corresponds to the user ID passed as a URL parameter.
class UserController extends Controller
{
public function show(User $user)
{
...
}
}
The reason you're seeing an empty model now is that Laravel will just pass and fresh model to the controller if it is not bound to a route parameter. In other words, if you forget to bind the model in your routes file automatic injection will just give you a new instance.
Note that if you are using a route resource the resulting routes should already have the correct parameters
Route::resource('users', 'UserController');
You can run php artisan route:list to confirm that your actual routes are correct.
Your problem is your controller is expecting two parameters like below:
public function show($id, User $user)
if you try:
public function show(User $user)
it should work correctly.
In your route you are passing only a single param like:
user/{user}
So if you dd the first param it will display the number 1 but if you pass that
to the model it will return the corresponding user as per what id you pass in the route.
The reason your User model was returning an empty object was because there was no value passed to it.
Also make sure your route placeholder: /{user} matches the variable name in
the controller: public function show(User $user).
Hope this helps.
I too came across with the same problem.
If your model having two or more words, you have to use only small letters like $modeModel as $somemodel.
public function show(SomeModel $somemodel)
{
...
}
I'm trying to find out how to return the relations I set up for my User model when using Sentry 2.
Normally, I have a user retrieved like this:
$user = User::find(1);
// get some relation
return $user->profile->profile_name;
However, now when I have Sentry 2 implemented I can retrieve the logged in user like this:
$user = Sentry::getUser();
This way I can easily access the users table in my DB, but how do I go about fetching the relations and methods I have set up in my User.php model?
This seems way to clumpsy, and not Laravel-ish:
User::find(Sentry::getUser()->id)->profile->wizard_completed;
It seems somewhat... backwards.
Can you guys help me out? =)
Extend Sentry creating your own User model with your relations on it:
<?php
use Cartalyst\Sentry\Users\Eloquent\User as SentryModel;
class User extends SentryModel {
public function profile()
{
return hasOne(...);
}
}
Publish sentry's config:
php artisan config:publish cartalyst/sentry
And tell Sentry to use your model, which now extending Sentry's has all of its functionalities plus yours:
'model' => 'User',
Then you'll be able to:
echo Sentry::getUser()->profile->wizard_completed;
Laravel routing functionality allows you to name a resource and name a controller to go with it. I am new to Laravel and would like to know if anyone knows how to extend the resources method in the route class provided.
Basically say I have: (which works fine)
/invoices
But say I want:
/invoices/status/unpaid
How is this achievable?
To see the basics of what I am doing check:
http://laravel.com/docs/controllers#resource-controllers
Resource controllers tie you into a specific URLs, such as:
GET|POST /invoices
GET|PUT /invoices/{$id}
GET /invoices/create
and so on as documented.
Since, by convention, GET /invoices is used to list all invoices, you may want to add some filtering on that:
/invoices?status=unpaid - which you can then use in code
<?php
class InvoiceController extends BaseController {
public function index()
{
$status = Input::get('status');
// Continue with logic, pagination, etc
}
}
If you don't want to use filtering via a query string, in your case, you may be able to do something like:
// routes.php
Route::group(array('prefix' => 'invoice'), function()
{
Route::get('status/unpaid', 'InvoiceController#filter');
});
Route::resource('invoice', 'InvoiceController');
That might work as the order routes are created matter. The first route that matches will be the one used to fulfill the request.