Correctly structuring Laravel project - php

I have a view that shows a line of 10 numbers in a table (it's a dashboard of stats).
They are information on sales today, tomorrow, the day after etc, split by some different states.
Currently I have some code like:
class Transaction extends Eloquent {
// other methods that aren't relevant
public function scopeConfirmed($query)
{
return $query->where('status', '=', 'Confirmed');
}
public function scopeBooked($query)
{
return $query->where('status', '<>', 'Cancelled');
}
public function scopeDaysAhead($query, $days)
{
$start = \Carbon\Carbon::now()->addDays($days)->toDateString();
$end = \Carbon\Carbon::now()->addDays($days+1)->toDateString();
return $query->where('date', '>=', $start)->where('date', '<', $end);
}
// few other similar scopes
}
Then in my view I have:
(Simplified)
<td>
{{Transaction::->daysAhead(0)
->booked()
->count()}}
</td>
<td>
{{Transaction::->daysAhead(0)
->confirmed()
->count()}}
</td>
<td>
{{Transaction::->daysAhead(1)
->confirmed()
->count()}}
</td>
<td>
{{Transaction::->daysAhead(2)
->confirmed()
->count()}}
</td>
So, I'm dealing with Eloquent calls in my view. In reality there are scopes by sales person and by location, so there are 10-20 values being shown.
I can move this back into the Controller by having a very fat load of with statements, or of course put it into an Array in the controller, but that doesn't seem to help massively.
What is the best way to deal with this?

Keep your views as logic less as possible, don't clutter your controllers with logic either. This would, to most people mean stuffing all the logic into models. Again this isn't an approach that helps with writing re-usable and more importantly testable code.
Laravel's IoC container and dependency injection is incredibly powerful and should be utilised to structure your applications in a testable way.
I can understand why you want to pass the query object around as well, this is something I used to do in my models. It seems to make sense however it quickly becomes apparent that creating a rigid query builder using a powerful query builder will create some quantity of wet code.
My suggestion would be to keep your model as slim as possible, use them to create relationships, set eloquent properties, validation rule arrays and nothing more. Abstract all logic into a repository based on an interface. Why? Well, the interface can be bound through the IoC to the class it should resolve to meaning that it can be dependency injected and swapped out easily (Mockery for example) whilst maintaining structural integrity in any replacements you may want to build (a Mongo, CouchDB etc. implementation for example).
namespace Repositories;
interface TransactionInterface {
public function findAll();
public function findById($id);
public function findByDaysAhead($start = 0, $end = 1)
}
And for the repository
namespace Repositories;
use Transaction;
class TransactionEloquent implements TransactionInterface {
public function findAll()
{
return Transaction::all();
}
public function findById($id)
{
$transaction = Transaction::find($id);
if ( ! $transaction )
{
throw new Exception("Transaction not found");
}
return $transaction;
}
public function findByDaysAhead($start = 0 , $end = 1)
{
// Create one query to return all the data you need
}
}
You can then bind this repository either in a new custom ServiceProvider or in your routes.php.
App::bind('Repositories\TransactionInterface', 'Repositories\TransactionEloquent');
Now you can dependency inject into your controller the interface that will resolve to your eloquent implementation. If you write a different repository implementation you can simply rebind it to the interface meaning it'll be used wherever the interface is injected (Mockery classes for example)
class ApplicationController extends BaseController {
public function __construct(Repositories\TransactionInterface $interface)
{
$this->repo = $interface;
}
public function getIndex()
{
return View::make('index', array('transactions' => $this->repo->findAll());
}
}
In your view you would only require a simple loop over your data and outputting, no logic required.
Obviously you can put as much logic as you like in the repository and as you can see your controllers, models and views fulfil only the responsibility they are intended for (OOPS Single Responsibility Principle)
This is a very short answer to what is a very complex question. I hope this guides you someway to writing testable and reusable modular code in Laravel.
Some 'light' reading
Laravel 4's IoC container
Laravel 4's Service Providers
NetTuts article on building L4 and Backbone apps Ignore the backbone part, this is a great walkthrough on L4's IoC bindings.
Where to place files etc.
Following PSR-0 specifications I would end up with a structure like this
- app
- {name of app}
- Repositories
* TransactionInterface.php
* TransactionEloquent.php
The namespaces for these two files would now be namespace {name of app}\Repositories
In composer you can add this to the autoload object :
"psr-0": {
"{name of app}" : "app/"
}
This will add all PSR-0 compatible namespaces to the autoloader, when you make changes you can use
composer dump-autoload
to rebuild the autoloader and include your new files (not always required but is better and faster than composer update constantly).
How many repositories?
I usually end up with 1+ repositories per model. For example I have a backbone collection of models and individual models in the front end.
Using Backbone.sync(param, collection) would always utilise a repo that handles input as an array of models. Where as Backbone.sync(param, model) would utilise a repo that handled a single model being sent. I would also have two Laravel resource controllers to handle this as well.
Service Providers
I place these in my application folders route, my app is called "MFL" in this instance
- MFL
- Repositories
- MFLServiceProvider.php
I add this to my service providers array in config\app.php
namespace MFL;
use Illuminate\Support\ServiceProvider;
class MFLServiceProvider extends ServiceProvider {
public function register()
{
// Register bindings here, don't use other service providers here
// you can't be sure they are loaded as of yet
$this->app->bind('MFL\Repositories\TransactionInterface', 'MFL\Repositories\TransactionEloquent');
}
public function boot()
{
// Do anything else here with assurance all service providers are
// fully loaded and the application is ready
}
}
Using this method, you don't pollute routes.php with IoC bindings and you can logically partition all your code into services. This is my preferred method for the latter reason.

There is a 3rd option in view composers. At the most basic level these are included in routes.php but I like to break them out by view path so composers/transactions.php would handle all the views in views/transactions like 'transactions.dashboard'. Given that as a view then the composer would be...
View::composer('transactions.dashboard', function ($view)
{
$view->day0_count = Transaction::->daysAhead(0)
->booked()
->count();
}
$day0_count is now available in the view.
<td>{{ $day0_count }}</td>

Related

Where to put business logic when you don't have a specified model for that feature? Laravel

I'm trying to improve my code OOP wise.
I have the tendancy to put some of my bussiness logic inside my Controller.
Some people told me this is not desirable.
I know that when you are working with Posts for example. You can simply put your bussiness logic in your Post.php Model.
I now have a feature where i upload an .xlsx file and it has to be checked and validated if the format of the .xlsx is correct.
It is currently inside ScheduleController#storeDeliveryXlsx.
But i don't have a specified model for this to store the validation inside?
Is this where Repositories design pattern is needed? Or is it fine to create a model that doesn't communicate with the database like: DeliveryFile.php where i put the logic that i later can use throughout my app like this: DeliveryFile::validate($file); or DeliveryFile::upload(file);.
I think i'm likely to re-use the same validation on the .xlsx for multiple instances. So i'd like to do something like Model::validate($file);. But i don't know where to put the code.
In this case, I would personally recommend using a Service. A service class is essentially for common functionality that you may repeat across multiple controllers. The Service Layer is a design pattern that will help you to abstract your shared logic to a common service i.e. our new Service Class.
So in your instance, you could have a Service class such as ExcelValidator and then use something like the following to structure your approach.
<?php
namespace App/Services;
class ExcelValidatorService
{
public function validate($file)
{
// our validate logic
}
}
And then in your controllers or models, you can call the ExcelValidator service to implement your repeated validate logic.
The phrase I now have a feature would keep on repeating itself in the course of the lifetime of the code you are writing. Having separate controller, service, model classes, OOP design, modular code would definitely help in that regard. Now it might be easier, but it will keep on becoming difficult with time
Recently I faced a similar problem, in my case I need to use, as model, a Restful API.
In composer.json I added under autoload
"psr-4": {
"App\\": "app/",
"MYCOMP\\": "app/MYCOMP/"
},
Under app folders I added MYCOMP folder with two subfolders Providers and Restmodels.
In config/app.php in providers array I added only:
MYCOMP\Providers\RestModelServiceProvider::class,
In app/MYCOMP/Providers/RestModelServiceProvider.php I register all providers and facades for my rest models:
public function register()
{
$loader = \Illuminate\Foundation\AliasLoader::getInstance();
$models = glob( realpath(__DIR__."/../") ."/RestModels/*/*RestModel.php");
foreach($models as $model){
$bnmodel = basename($model);
if($bnmodel !== "BaseRestModel.php" && $bnmodel !== "BaseFacadeRestModel.php"){
list($n, $niente) = explode("RestModel.php", $bnmodel);
list($bnnoext, $niente) = explode(".php", $bnmodel);
$res = $n.'Repository';
$fold = basename(dirname($model));
$nc = "\\MYCOMP\\RestModels\\".$fold."\\".$bnnoext;
$this->app->bind($res, function($app) use ($nc) {
return new $nc;
});
$loader->alias($res, $nc."Facade");
}
}
}
This code is specific for my project and for how I structured folders.
For all rest models I have two files:
app/MYCOMP/RestModels/{ModelName}/{ModelName}RestModel.php
app/MYCOMP/RestModels/{ModelName}/{ModelName}RestModelFacade.php
The only exceptions are: BaseRestModel and BaseFacadeRestModel these classes are extended by all RestModel and RestModelFacade. So I'd implement something like validate under BaseRestModel.
BaseFacadeRestModel just contains:
<?php
namespace MYCOMP\RestModels\Base;
use Illuminate\Support\Facades\Facade;
class BaseFacadeRestModel extends Facade{
private $facadeName;
protected static function getFacadeName(){
list($senzasuffisso, $niente) = explode("RestModelFacade", static::class);
$nc = last(explode("\\", $senzasuffisso));
return $nc;
}
protected static function getFacadeAccessor() {
return static::getFacadeName().'Repository';
}
}
So all the other Facades work just exteding BaseFacadeRestModel.

Same Laravel resource controller for multiple routes

I am trying to use a trait as a typehint for my Laravel resource controllers.
The controller method:
public function store(CreateCommentRequest $request, Commentable $commentable)
In which the Commentable is the trait typehint which my Eloquent models use.
The Commentable trait looks like this:
namespace App\Models\Morphs;
use App\Comment;
trait Commentable
{
/**
* Get the model's comments.
*
* #return \Illuminate\Database\Eloquent\Relations\MorphMany
*/
public function Comments()
{
return $this->morphMany(Comment::class, 'commentable')->orderBy('created_at', 'DESC');
}
}
In my routing, I have:
Route::resource('order.comment', 'CommentController')
Route::resource('fulfillments.comment', 'CommentController')
Both orders and fulfillments can have comments and so they use the same controller since the code would be the same.
However, when I post to order/{order}/comment, I get the following error:
Illuminate\Contracts\Container\BindingResolutionException
Target [App\Models\Morphs\Commentable] is not instantiable.
Is this possible at all?
So you want to avoid duplicate code for both order and fulfillment resource controllers and be a bit DRY. Good.
Traits cannot be typehinted
As Matthew stated, you can't typehint traits and that's the reason you're getting the binding resolution error. Other than that, even if it was typehintable, the container would be confused which model it should instantiate as there are two Commentable models available. But, we'll get to it later.
Interfaces alongside traits
It's often a good practice to have an interface to accompany a trait. Besides the fact that interfaces can be typehinted, you're adhering to the Interface Segregation principle which, "if needed", is a good practice.
interface Commentable
{
public function comments();
}
class Order extends Model implements Commentable
{
use Commentable;
// ...
}
Now that it's typehintable. Let's get to the container confusion issue.
Contexual binding
Laravel's container supports contextual binding. That's the ability to explicitly tell it when and how to resolve an abstract to a concrete.
The only distinguishing factor you got for your controllers, is the route. We need to build upon that. Something along the lines of:
# AppServiceProvider::register()
$this->app
->when(CommentController::class)
->needs(Commentable::class)
->give(function ($container, $params) {
// Since you're probably utilizing Laravel's route model binding,
// we need to resolve the model associated with the passed ID using
// the `findOrFail`, instead of just newing up an empty instance.
// Assuming this route pattern: "order|fullfilment/{id}/comment/{id}"
$id = (int) $this->app->request->segment(2);
return $this->app->request->segment(1) === 'order'
? Order::findOrFail($id)
: Fulfillment::findOrFail($id);
});
You're basically telling the container when the CommentController requires a Commentable instance, first check out the route and then instantiate the correct commentable model.
Non-contextual binding will do as well:
# AppServiceProvider::register()
$this->app->bind(Commentable::class, function ($container, $params) {
$id = (int) $this->app->request->segment(2);
return $this->app->request->segment(1) === 'order'
? Order::findOrFail($id)
: Fulfillment::findOrFail($id);
});
Wrong tool
We've just eliminated duplicate controller code by introducing unnecessary complexity which is as worse as that. ๐Ÿ‘
Even though it works, it's complex, not maintainable, non-generic and worst of all, dependent to the URL. It's using the wrong tool for the job and is plain wrong.
Inheritance
The right tool to eliminate these kinda problems is simply inheritance. Introduce an abstract base comment controller class and extend two shallow ones from it.
# App\Http\Controllers\CommentController
abstract class CommentController extends Controller
{
public function store(CreateCommentRequest $request, Commentable $commentable) {
// ...
}
// All other common methods here...
}
# App\Http\Controllers\OrderCommentController
class OrderCommentController extends CommentController
{
public function store(CreateCommentRequest $request, Order $commentable) {
return parent::store($commentable);
}
}
# App\Http\Controllers\FulfillmentCommentController
class FulfillmentCommentController extends CommentController
{
public function store(CreateCommentRequest $request, Fulfillment $commentable) {
return parent::store($commentable);
}
}
# Routes
Route::resource('order.comment', 'OrderCommentController');
Route::resource('fulfillments.comment', 'FulfillCommentController');
Simple, flexible and maintainable.
Arrrgh, wrong language
Not so fast:
Declaration of OrderCommentController::store(CreateCommentRequest $request, Order $commentable) should be compatible with CommentController::store(CreateCommentRequest $request, Commentable $commentable).
Even though overriding method parameters works in the constructors just fine, it simply does not for other methods! Constructors are special cases.
We could just drop the typehints in both parent and child classes and go on with our lives with plain IDs. But in that case, as Laravel's implicit model binding only works with typehints, there won't be any automatic model loading for our controllers.
Ok, maybe in a better world.
๐ŸŽ‰Update: See PHP 7.4's support for type variance ๐ŸŽ‰
Explicit route model binding
So what we gonna do?
If we explicitly tell the router how to load our Commentable models, we can just use the lone CommentController class. Laravel's explicit model binding works by mapping route placeholders (e.g. {order}) to model classes or custom resolution logics. So, while we're using our single CommentController we can utilize separate models or resolution logics for orders and fulfillments based on their route placeholders. So, we drop the typehint and rely on the placeholder.
For resource controllers, the placeholder name depends on the first parameter you pass to the Route::resource method. Just do a artisan route:list to find out.
Ok, let's do it:
# App\Providers\RouteServiceProvider::boot()
public function boot()
{
// Map `{order}` route placeholder to the \App\Order model
$this->app->router->model('order', \App\Order::class);
// Map `{fulfillment}` to the \App\Fulfilment model
$this->app->router->model('fulfillment', \App\Fulfilment::class);
parent::boot();
}
Your controller code would be:
# App\Http\Controllers\CommentController
class CommentController extends Controller
{
// Note that we have dropped the typehint here:
public function store(CreateCommentRequest $request, $commentable) {
// $commentable is either an \App\Order or a \App\Fulfillment
}
// Drop the typehint from other methods as well.
}
And the route definitions remain the same.
It's better than the first solution, as it does not rely on the URL segments which are prone to change contrary to the route placeholders which rarely change. It's also generic as all {order}s will be resolved to \App\Order model and all {fulfillment}s to the App\Fulfillment.
We could alter the first solution to utilize route parameters instead of URL segments. But there's no reason to do it manually when Laravel has provided it to us.
Yeah, I know, I don't feel good, too.
You can't typehint traits.
However, you can typehint interfaces. So you can create an interface that requires the methods from the trait and resolve that. Then have your classes implement that interface and you should be OK.
EDIT: As #Stefan has kindly pointed out, it's still likely to be difficult to resolve the interface to a concrete class because it will need to resolve to different classes under different circumstances. You could access the request in the service provider and use the path to determine how to resolve it, but I'm a bit dubious of that. I think putting them in separate controllers and using inheritance/traits to share common functionality may be a better bet, since the methods in each controller can type hint the required object, and then pass them to the equivalent parent method.
For my case I have following resources:
Route::resource('books/storybooks', 'BookController');
Route::resource('books/magazines', 'BookController');
After php artisan route:cache and it creates the route to tie up with 'magazine' model.
The solution is to add following line in app/Providers/RouteServiceProvider.php > boot() method, after parent::boot():
Route::model('magazine', \App\Book::class);
Pay attention to the singular and plural.

Laravel error interface class does not exist

I am very new to "Advanced Laravel" so to speak, however I do know most of the basics and I am trying to understand what namespacing, interfaces and repositories is all about, since I came across it not so long ago.
However, I am getting the following error, and I have no idea what I am doing wrong:
Class app\models\Interfaces\CategoriesInterface does not exist
Below is my code:
Routes.php
App::bind('App\Models\Interfaces\BaseInterface', 'App\Models\Repositories\BaseRepository');
CategoriesController.php
<?php
use app\models\Interfaces\CategoriesInterface;
class CategoriesController extends BaseController
{
protected $categories;
public function __construct(CategoriesInterface $categories)
{
$this->categories = $categories;
}
BaseInterface.php
<?php
interface BaseInterface
{
public function all();
}
CategoriesInterface.php
<?php namespace App\Models\Interfaces;
interface CategoriesInterface extends BaseInterface { }
CategoriesRepository.php
<?php namespace app\models\Repositories;
use App\Models\Interfaces\CategoriesInterface;
use Categories;
class CategoriesRepository implements CategoriesInterface
{
public function all()
{
$categories = $this->categories->all();
return $categories;
}
}
EloquentCategoriesRepository.php
<?php namespace app\models\Repositories;
use App\Models\Interfaces\CategoriesInterface;
class EloquentCategoriesRepository implements CategoriesInterface {
public function all()
{
return Categories::all();
}
Try name spacing the classes/interfaces properly. EloquentCategoriesRepository.php and CategoriesRepository are having app instead of App in the namespace. And CategoriesController too needs to use App\.. not app\...
I see you are trying to implement the repository pattern, which at first it might seem a bit 'advanced' but it's actually pretty simple.
So the basic idea is to abstract the data layer of your application with the database to make your transitions from one DBS to another(ex. Mysql to Mongo).
In other words your are trying to make the business logic of your application independent to the data layer (Where you query your collections/instances), so when you reach a point that you might want to change your database you can just implement another repository. The Interfaces are there to provide a contract between your application and the data layer.
Laravel implementation of the repository pattern it's pretty straight forward.
Create your interface
Create your interface's repository (actual implementation)
Bind the repository using a service provider class (Or in your case App::bind)
Instantiate the dependency in to your controller using the repository
Don't forget to auto load your namespaces using psr-04.
In your case I think the problem is you are not autoloading the namespace.
Also CategoriesRepository.php & EloquentCategoriesRepository.php are both Eloquent repositories and will return Eloquent collections. To return an array of stdClass (standar PDO) you will have to use the \DB facade.
If my answer does not cover you please take a look here

Laravel extend Eloquent and 3rd party class

I'm currently working on my first PHP/Laravel 4 project, I'm developing on it a storage class to add Eloquent support to a 3rd party library.
My EloquentStorage class extends the AbstractStorage class from the library, and I make usage of most of AbstractStorage methods. Now that I want to add Eloquent support to my new EloquentStorage class, I faced the fact that PHP does not support multiple inheritance.
Is there a proper way to define an Eloquent model without extending it as:
class MyClass extends Eloquent {}
And, if not, how to deal with such situation when I need to extend 3rd party class and also extend Eloquent? Maybe using Laravel's IoC?
I think your model should extend from Eloquent, and instead be accessed through a repository. Your repository can have a $storage property, and would be responsible for calling the appropriate methods on your AbstractStorage implementation. Below is more pseudo- than actual code, but illustrates where you can plug in your implementation for an update operation.
class MyClass extends Eloquent
{
/* Normal Eloquent model implementation */
}
class MyRepository
{
protected $storage;
protected $myClass;
public function __construct(MyClass $myClass, AbstractStorage $storage)
{
$this->myClass = $myClass;
$this->storage = $storage;
}
public function update($id, $data)
{
// This is just an example operation, basically here's your chance to call
// the 3rd-party implementation. Here is pre-eloquent update, but can be
// after
$this->storage->update($id, $data);
// Use the empty Eloquent class property instance to obtain an instance of
// the requested model
$instance = $this->myClass->find($id);
// set instance properties
$instance->save();
// Example post-eloquent update
$this->storage->update($id, $data);
}
}
class MyStorage extends AbstractStorage { /* Your Storage Implementation */ }
$repo = new MyRepository(new MyClass, new MyStorage);
// Update item id 42's foo property
$repo->update(42, [ 'foo' => 'bar' ]);
A benefit to this approach is that the construction of the repository itself can be offloaded to the IoC through a Service Provider, and be injected inside of a controller / form validator etc, which means the execution will become automatic and hide the underlying complexity of the 3rd party library from the rest of the system (the repository helps keep your 3rd party abstraction from leaking).
Another benefit is that you don't need any special code in your eloquent models having anything to do with your completely unrelated 3rd party code. All of the logic is encapsulated in a single spot, and can even be shared amongst multiple models. Want to change 3rd party providers? Write a new implementation of AbstractStorage, update the service provider and you're done.
One other benefit is improved testability. Instead of statically utilizing an eloquent model directly (a la $user = User::find($id)) you would be manipulating your repository object instead ($user = $this->repo->find($id)). Since your repository can be trivially mocked and itself be tested (without also testing Eloquent or hitting the database), you can write integration tests on all of your controller routes and know the moment that changes to your codebase break your business rules.

Are Namespaces necessary everywhere in Laravel?

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?
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');
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.

Categories