Reputation: 385
Im new to Laravel and namespaces, but a colleague told me i have to use the namespaces and place all my models in a folder in the app directory, named after the project.
As far as i know this means that in every single controller that uses one or more models, have have to set "use" for every model my controller needs. Example:
<?php
use Foo\Entities\Entity;
use Foo\Entities\Inheritance;
use Foo\Entities\Type;
class EntitiesController extends BaseController {
public function index()
{
$inheritances = Inheritance::all();
$entities = Entity::all();
return View::make('settings/entities')
->with('entities', $entities)
->with('inheritances', $inheritances);
}
}
If we asume that the associated models above will be used everywhere, would it be completely crazy to put the models in the /app/model/ folder and if a controller need a model which overwrite the standard system, then use namespaces?
Upvotes: 0
Views: 1531
Reputation: 87719
First things first: namespaces are NOT a Laravel thing, but a PHP feature created to better organize our code.
So, if you want your code organized, you should use namespaces for everything and, yes, you'll have to add 'use' clauses in the top of most of your PHP files. But in Laravel you also can be free to not use namespaces at all, you just have to add your autoload classes directories to your composer.json
file:
"autoload": {
"classmap": [
"models"
],
},
Execute
composer dumpautoload
So Composer read all files in your models folder, to create a class map of them, and then you can just drop all uses clauses:
class EntitiesController extends BaseController {
public function index()
{
$inheritances = Inheritance::all();
$entities = Entity::all();
return View::make('settings/entities')
->with('entities', $entities)
->with('inheritances', $inheritances);
}
}
To not use namespaces in your PHP application, these days, may be considered a code smell. The only 'part' of Laravel where people doesn't usually use namespaces is Controllers, but this is also changing in Laravel 5, where controllers will be namespaced by default, but still, you will have the option to not use them, because this is a Composer/PHP thing, not Laravel.
Taylor Otwell has 3 big things always in mind when creating features and evolving Laravel: Best practices, fast coding and beautiful code.
EDIT
Answering your comment, if all your controllers needs to have access to some service or even model, why not add it to your BaseController?
But you may have to take a read at the repository pattern, because your controllers should not really be aware of your models. Developers are now creating a new layer (repository) between controllers and models, and perform the operations in those layers. You can, also, make use of Laravel Dependency Injection to help you with those use
clauses you don't like.
It would be something like this:
Create a repository interface:
interface EntityRepositoryInterface {
}
Create the repository:
use Foo\Entities\Entity;
class EntityRepository {
public function find($id)
{
return Entity::find($id);
}
public function all()
{
return Entity::all();
}
}
Create your controllers using your repository:
class EntitiesController extends BaseController {
public function __construct(EntityRepositoryInterface $entityRepository)
{
$this->entityRepository = $entityRepository;
}
public function index()
{
$entities = $this->entityRepository->all();
return View::make('settings/entities')
->with('entities', $entities);
}
}
And you have to tell Laravel Dependency Injection what to instantiate when it needs a EntityRepositoryInterface
:
App::bind('EntityRepositoryInterface', 'Foo\Entities\EntityRepository');
Upvotes: 1
Reputation: 24661
There's nothing wrong with putting your models anywhere you like. In fact, I put all my models that extend directly from Eloquent in app/models
. You are free to follow this, or not follow it, in your own project.
However, this does come with a caveat. Very few of my classes actually directly interact with these models (Repositories are pretty much it). Those I do put in separate namespaces which are then injected into my controllers. Consequently, I must either use
each repository that a controller needs at the top of each file or specify the fully qualified class name every time I reference it.
Upvotes: 0