Skip to content
This repository has been archived by the owner on Jul 16, 2021. It is now read-only.

[Proposal] Change Model location #1550

Open
ghost opened this issue Mar 8, 2019 · 28 comments
Open

[Proposal] Change Model location #1550

ghost opened this issue Mar 8, 2019 · 28 comments

Comments

@ghost
Copy link

ghost commented Mar 8, 2019

For small projects, using the app folder to place eloquent models is OK, but when working with larger projects, this may become messy, since the inclusion of model directories will be necessary. Mixing the functional structure of Laravel with the organizational structure of the modelling part seems not a good practice.

For example:
I have two models, contest and notebook, and they both have a topic related to them. Since both topic are too different to be grouped in a single model, I have distinguished them in the database. But having NotebookTopic and ContestTopic seems wrong, so I create both Notebook and Contest directories. Now I'm mixing organizational directories with structural ones.

Solution:
Creating a folder named Models in the app directory. It may even be a option to add it to the composer psr-4 for quicker reference: "Model\\": "app/Models".

@mfn
Copy link

mfn commented Mar 8, 2019

Seems to be a duplicate of #1091

@martinbean
Copy link

I’m sure @taylorotwell has said a few times now that Laravel will not be shipped with a Models directory.

You‘re free to organise your domain models how you see fit. Personally, I group them in directories relating to “domain”, i.e.

  • /app
    • /Billing
      • Coupon.php
      • /Gateways
        • /Contracts
          • PaymentGateway.php
        • PaypalPaymentGateway.php
        • StripePaymentGateway.php
    • /News
      • /Events
        • ArticlePublished.php
      • Category.php
      • Article.php
    • /Shop
      • /Catalog
        • Category.php
        • Product.php
        • Sku.php
      • /Orders
        • /Events
          • OrderPlaced.php
          • OrderPaid.php
        • Item.php
        • Order.php
      • /Shipping
        • /Events
          • OrderShipped.php
        • /Listeners
          • SendShipmentNotificationToCustomer.php
        • Shipment.php

…and so on.

@blood72
Copy link

blood72 commented Mar 20, 2019

if you just want to put it in the 'Models' folder, override make:model command.
you don't have to change composer.json

php artisan make:command ModelMakeCommand

<?php

namespace App\Console\Commands;

use Illuminate\Foundation\Console\ModelMakeCommand as Command;

class ModelMakeCommand extends Command
{
    /**
     * Get the default namespace for the class.
     *
     * @param  string  $rootNamespace
     * @return string
     */
    protected function getDefaultNamespace($rootNamespace)
    {
        return "$rootNamespace\Models";
    }
}

@ollieread
Copy link

This seems a bit excessive, just prefix your model name

php artisan make:model Models\\MyModel

The above will create app/Models/MyModel.php.

@ghost
Copy link
Author

ghost commented Apr 29, 2019

And that would end up being pratically the same as to what I'm proposing, but coming out of the box would help the developers that are starting laravel to organize better their stuff.

@martinbean
Copy link

coming out of the box would help the developers that are starting laravel to organize better their stuff.

Whilst frustrating those who don’t store their models in a Models directory.

@lsotoangeldonis
Copy link

coming out of the box would help the developers that are starting laravel to organize better their stuff.

... those who don’t store their models in a Models directory.

I tottaly understand the reasonings here but this part still sounds funny.

Models not in models.
Routes not in routes.
And so on.

Maybe keep in it simple could be the best on these cases.

@ollieread
Copy link

ollieread commented Aug 23, 2019

I would imagine that a vast amount of those that do not use the models directory, do so because it has been the default for so long. I'd even go as far as to say that if the models directory was added by default, a lot of them would just use it that way. It's rare that I find someone not using it to be honest with you.

That being said, it doesn't need to be default. The location of the models have no effect on how the codebase works.

Realistically, people should be organising their code, so it may be a sensible thing to set as the default to help encourage that.

@connecteev
Copy link

+1
I have a large Laravel project at this point (As I'm sure a lot of devs do), and there are 30+ models cluttering up my workspace. It really makes things hard to find and reduces my productivity.

I can't collapse the models into a folder like I can do for controllers, providers, etc. Please consider moving all models to App/Models, plenty of people (myself included) are suffering through this. See this workaround, which is rather clunky:
https://medium.com/@codingcave/organizing-your-laravel-models-6b327db182f9

@ollieread
Copy link

ollieread commented Oct 20, 2019

@connecteev that work around is unnecessary. If you're using an IDE (which you should be) just do a refactor > move class.

Also, there's only a single reference to that model that means anything, and that's in the auth config. Super simple manual changes.

You don't need to override the command, just prefix the model name with Models\\.

@martinbean
Copy link

@connecteev There’s nothing stopping you putting your models in folders yourself.

@connecteev
Copy link

@ollieread thanks clarifying. I'm using Visual Studio code and don't see an option to refactor and move or refactor and rename.

@martinbean
Copy link

@connecteev Visual Studio Code isn’t a great editor for PHP out of the box. You’ll need to install an extension to do automatically re-factoring.

@michaeldyrynda
Copy link

What about those of us that keep our models in an entirely separate package?!

The framework already provides the tools to allow you to put your models wherever you want them.

@prezire
Copy link

prezire commented Oct 20, 2019

If controllers are in the Controllers folder, Views are in the Views folder, routes are in the Routes folder, Commands are in the Commands folder, providers are in the Providers folder, Listeners, Mail, Jobs, Migrations, Configs, Middlewares, Requests, etc. Why aren't models in the Models folder? We know that some people don't put models in the Models folder. But why? A good explanation would be nice.

@brunogaspar
Copy link

It's kinda explained here https://laravel.com/docs/6.x/structure#introduction

@prezire
Copy link

prezire commented Oct 21, 2019

It just says "some developers". It clearly shows that, those "some developers", who break the conventions, are being favored in contrast to the MVC structure being placed in their respective directories based on practices used by many, who up to now followed the MVC practices from the start.

I believe those "some developers" are confusing Models with Services https://softwareengineering.stackexchange.com/questions/230307/mvc-what-is-the-difference-between-a-model-and-a-service/230312. Laravel is favoring those "some developers" instead of enforcing a real and elegant MVC structure through folder structures and namespaces.

I can have business logic, Traits, Contracts, VOs, Enums, Vendors, placed inside the Services directory instead of mixing them in the App directory along with models. I can use those Services wherever I want, either calling them from controllers, migrations, seeders or other services for that matter. I can even place a single file called helpers.php under the Services directory, which is way more elegant to look at in my IDE's sidebar.

@martinbean
Copy link

People are free to put their models in a “Models” folder if they wish:

$ php artisan make:model "Models\Foo"

@prezire
Copy link

prezire commented Oct 21, 2019

That's understandable. However, wouldn't it be better to have it the other way around? Have the models placed in the Models directory as default. And in contrast, let those "some developers" who don't want their models in the Models directory, move it manually outside the Models directory instead.

It's odd having a command make:model where the files themselves aren't placed in the Models directory.

@martinbean
Copy link

However, wouldn't it be better to have it the other way around? Have the models placed in the Models directory as default. And in contrast, let those "some developers" who don't want their models in the Models directory, move it manually outside the Models directory instead.

No. Because for “some developers” like me who is working on a project following DDD naming conventions, our “models” are in sub-directories of a Domain directory (i.e. app/Domain/Catalog). Right now, I can do:

$ php artisan make:model "Domain\Catalog\Product"

If this command is changed to automatically put classes in a Models directory, then my team and I can no longer make use of it.

@prezire
Copy link

prezire commented Oct 22, 2019

However, wouldn't it be better to have it the other way around? Have the models placed in the Models directory as default. And in contrast, let those "some developers" who don't want their models in the Models directory, move it manually outside the Models directory instead.

No. Because for “some developers” like me who is working on a project following DDD naming conventions, our “models” are in sub-directories of a Domain directory (i.e. app/Domain/Catalog). Right now, I can do:

$ php artisan make:model "Domain\Catalog\Product"

If this command is changed to automatically put classes in a Models directory, then my team and I can no longer make use of it.

Good luck to other teams (who practice and follow the original MVC structure) who need to organize their Models different than yours.

@michaeldyrynda
Copy link

Like they can right now?

The existing make:model command gives you the flexibility to put your models exactly where you need them to be.

For smaller apps with a handful of models, I’ll just leave them right in app/. Move things when the pain drives you to, not just because some methodology prescribed it.

@prezire
Copy link

prezire commented Oct 22, 2019

It still sounds funny using an MVC framework and not following the basic methodology behind it.

@martinbean
Copy link

Good luck to other teams (who practice and follow the original MVC structure)

You don’t really need luck to run php artisan make:model "Models\Foo"

@mattstauffer
Copy link
Member

@prezire There's nothing about MVC that requires or even suggests models be under a Models directory. You've made your opinion clear, and it's based on a misunderstanding of what "must" be true in MVC. Further, Laravel doesn't really care to do what MVC or any other pattern requires it to do, but what makes the most sense.

@prezire
Copy link

prezire commented Oct 22, 2019

@prezire There's nothing about MVC that requires or even suggests models be under a Models directory. You've made your opinion clear, and it's based on a misunderstanding of what "must" be true in MVC. Further, Laravel doesn't really care to do what MVC or any other pattern requires it to do, but what makes the most sense.

Based on the number of Likes, fair enough.

@netpok
Copy link

netpok commented Oct 24, 2019

I made a package for this:
https://packagist.org/packages/netpok/namespaced-laravel-models

@crynobone
Copy link
Member

crynobone commented Jan 3, 2020

I just released orchestra/canvas which bring make:** command to Laravel and Laravel Packages. This would bring all the make command to package development (we're using Symfony Command) under the hood.

As for Laravel, you should be able to customize the configuration using canvas.yaml which should sit at the root directory (same level as composer.json).

preset: laravel

namespace: App

model:
  namespace: App

If you want to customize the model namespace, just change it to

model:
  namespace: App\Model

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests