Laravel: A Beginner's Guide To Structuring Your App

David Belich
October 3, 2022
computer screen with lines of code


When you’re developing a large Laravel app with extensive functionality, it can often be a challenge to keep the code structured cleanly and correctly. If you’re in the position to take over an existing app project, it can be even more challenging as you struggle to clean up someone else's code. New app developers have a tendency to do whatever is necessary to make code work, whether it's hard coding variables or duplicating functions to wherever they are needed. While this may work for the short term, any good developer will know that this isn’t a sustainable approach, especially as you work towards building out new functionality and maintaining an existing app.

In Laravel, there are multiple ways and places to write code. Between Models, Controllers, Events, Traits, and more, creating a proper hierarchy can sometimes feel overwhelming and confusing. Knowing what goes where and structuring your code to be flexible and reusable is the key between a bloated codebase and an easy-to-maintain app. This blog post covers the basics of structuring a Laravel app and explains what each class type is for.


Models are the basis of good object-oriented development and are the bedrock of your Laravel app. Models should be created for each object within your application, allowing you to define and create a group of functions and relationships that are unique to each model. Often models can directly reflect a table in your database, such as Post, User, Book, Tag, etc, though they can also reference numerous other situations or variations of other models, such as EditingUser, SupportingPartner, MysteryNovel, etc.

Models should mostly contain basic relationships between them and other models, scopes for database queries, and functions to return attributes of the object. They should also be used to determine what fields are fillable when new models are created, casting fields with appropriate types, as well as providing a better understanding of what options and values are available. Models should not be used as a catch-all for extensive code relating to their objects. Model functions should be used for referencing themselves and their relationship but never for altering themselves.

Example of model functions

class Book extends Model {

//limiting the query to only include books on sale

public function scopeWithOnSale(Builder $query)

return $this->whereSale(1);


//returns the boolean sale status of a book

public function getSaleStatusAttribute(){

return $this->sale;


//defines the relationship between a book and its authors

public function authors(){

return $this-belongsToMany(Author::class);


These are only several examples of model functions. However, what happens if you have related models such as Book and Novel, that have their own unique functions and fields but could share common code between them? In our next blog, we will look at this problem and discuss how shared traits are a great way to share common code between models.


Want to talk about how we can work together?

Ryan can help

Ryan Wyse