Why I Created “Eloquent by Example”
As a freelancer, I have the opportunity to work with a great variety of teams of all different programming backgrounds and levels of experience. Over the years I began to notice the same trends in how teams that were new to Laravel tended to set up their development workflow, and how they could make life easier on themselves.
Eloquent by Example was an attempt to get people started on the right track. There are 14 lessons in all (at the time of writing this) that are split between gaining a better understanding of how Eloquent works and creating a faster, more efficient workflow.
Learning the underpinnings of the Eloquent ORM is a gradual process that comes through practice. The tools are something you can learn in a few hours and put to immediate use. So in the spirit of “If you learn anything from my course, learn this”, here are a few highlights of what I think every Laravel developer must be comfortable with to work in a professional manner:
Use Data Seeders: This list isn’t really ranked, since many of the items work in tandem, but if there is one thing I’d like to see teams make better use of it is data seeding.
Data seeding is for more than just generating thousands of rows to test performance. I think the most important use from a development standpoint is that it allows you with a simple command to clean out your cruft data. No more “hmmm…could just be dirty data” excuses. Build or test a feature, then run artisan db:seed and you’re back to fresh data. More than that, it will help you catch silly mistakes because it allows you to use realistic data while working. When “Johnny New York” pops up on the profile page you’ll know a lot quicker something is wrong than if it says “Mr. asfdhfj rehrwh”. Lastly, you can seed in a way that your local machine reproduces the same data as the staging server your users are testing on, helping to lessen those “can’t reproduce” instances.
Use Factories: I can’t think of any use cases for these outside of seeding & testing, but boy! do they shine for those purposes. A factory is more than just a create technique; it has a callback with Faker pre-loaded and the ability to (as of 5.3) tag them with “states” , which let you make, for example, different User Model Factories for a customer, admin, manager, etc. This lets you create a single point to create data for all your tests, allowing you to quickly adapt to changes and cut down on a lot of boring copy/paste boilerplate that leads to careless mistakes.
Use Migrations: Thankfully, I rarely run across cases anymore where migrations were not used at least in the beginning. I have had many a case where they were not properly maintained going forward, and so instead of jumping in with a team and getting straight to work, I spent a better part of the morning getting my database up and running.
Creating data migrations from the Model Generator is something that helps us at Mahana Designs crank out a lot of database querying structure very quickly. I don’t think we could offer as quick a turnaround with out them — I’m sure of it.
You should have a test, process or even just a simple reminder to check your migrations and seeding daily (perhaps weekly once things are more stable, but really this isn’t a very long test). To expand on that idea, I think that once a month someone should try to create a fresh install of your entire site setup, as if they were a new team member, and update documentation.
The other point I would make here is that, while you are still pre-live and data is “flushable”, make changes to the original table creation script rather than a new file every time you need to add a field somewhere. Those files will add up! If you are using seeders, this won’t make any difference to anyone.
Debug with Tinker: Surprisingly, Tinker isn’t even documented anymore that I can tell — I’m not sure where people continue to learn about it. If you haven’t heard of it, it is a PHP REPL tool just like Python and Ruby have where you can access pretty much any of your codebase using php and function calls.
Aside letting you escape from “dd() Hell”, I’ve found that just like TDD, Tinker helps me spot less testable areas of my code and go in to fix them. I can use it to quickly query my data via a code class, which in turn helps me more easily spot places where something is obviously wrong.
Learn to Use Scopes: Because they are where you should be putting your low-level business logic. Don’t write:
->where('age', '>', 30)...
Make something that “comments itself” and is reusable. You, know — functions?
return $this->where('age', '>', 30);
Scopes are far more flexible than most people realize, so look into what all you can do with them to make your code more regular.
Know when to use Eloquent, and when not to: Eloquent is an ORM, which means it is a system of integrated classes. It is excellent for managing your internal application and business logic. It is slow for running large reporting queries.
Knowing the right tool for the job is one of our important roles as developers. I find we often don’t think about that inside the framework or library we chose. Unfortunately, as the number of things we need to know has increased over the years, and the focus has shifted to front-end technologies, familiarity and comfort with more complex SQL has slipped. A great many people flat out do not understand how to write things as simple as outer joins or group by’s; this has lead to an over-dependence on code libraries.
When adding new data querying code, ask yourself if this is an integrated part of the application, or something that could (theoretically!) be run in a DB Admin tool and exported to a csv file. If the latter, try to write it as raw SQL or with the QueryBuilder. Don’t be afraid to go to places like Stackoverflow and ask for help not just with the query, but with the best ways to index it.
Summary: Laravel’s Eloquent ORM is a large, complex library on the scale of Doctrine, and like those others, it will take some time to get fully comfortable with. Aside from that, there are a lot of great support tools that I’d recommend making the effort to immediately integrate into your daily workflow — you will quickly reap the benefits!