Unlikenesses A Backend Developer

Lessons from Laracasts, Part 1

24 March 2018

Let's Build a Forum with Laravel and TDD is a mega-tutorial (102 lessons) by Jeffrey Way on his Laracasts site. It's a massive, time-intensive beast that contains lots of useful info, and not least gives the opportunity to watch someone build a fairly complex website from scratch. But its size means that a lot of little tricks and tips are hidden away inside the videos. While each lesson's title reflects a particular feature Jeffrey Way wants to build, I found that there are also particular technical nuggets of info to be found among the broader strategies. So this is a list of any little snippets that cropped up in the course, just minor points I didn't know or found useful. This post contains 50 tips, covering lessons 1-42. See Part 2 here!


When making a model in artisan, and -mr to make the migration (m), and a resourceful controller (r). Or use c for a plain controller. [Source]


For testing we can use an SQLite database in memory. In phpunit.xml set DB_CONNECTION to sqlite and DB_DATABASE to :memory:. [Source]


latest() is an Eloquent relation that is basically an alias for orderBy('created_at', 'desc'). [Source]


Put code common to all tests in a test file in a setUp method that calls parent::setUp();. [Source]


Call diffForHumans() on Carbon instances (like created_at fields in Eloquent models) to output something like "2 days ago". [Source]


Add the --filter flag to phpunit to run only one test. [Source]


Instead of specifying mass-assignable fields in a model with fillable, you can set the $guarded variable to block specific fields, or set it to an empty array to make every field assignable. [Source]


back() is a helper function to return the user to the previous location. [Source]


Note the distinction between create and make model factory methods: create persists the model to the database, while make only stores it in memory. [Source]


The raw model factory method returns an array of the model data, rather than the Eloquent model. [Source]


Add only() to restrict middleware to particular methods in a controller. E.g. in the constructor:



Or use except() for the opposite. [Source]


Use the exists validation rule to check whether a given field exists in a specified database table. [Source]


You can use whereSlug and whereId as aliases for where('slug', $slug) and where('id', $id) in Eloquent calls. [Source]


To change the key used in route-model binding, override the getRouteKeyName method in your model. E.g.

public function getRouteKeyName()
  return 'slug';



If you need some data to be passed to all your views, you don't need to use a view composer, you can use the much simpler share method. [Source]


JW says that he uses "query objects" - classes that correspond to a complex SQL query - in the Laracasts codebase. E.g. App/Queries/ThreadsQuery. [Source]


You can retrieve only a portion of the request data using $request->only(['foo', 'bar']). It saves requesting everything then filtering through it. [Source]


Performing count() on a relationship given as a dynamic property (e.g. $thread->replies->count()) requires a redundant SQL query that will fetch all the replies. If we substitute the method for the property (e.g. $thread->replies()->count()) the SQL query only gets the count of the replies. As the docs say: "all types of Eloquent relationships also serve as query builders, allowing you to continue to chain constraints onto the relationship query before finally executing the SQL against your database". [Source]


The Eloquent load method permits "lazy eager loading", i.e. eager loading a relationship after the model has been retrieved. [Source]


The Eloquent withCount method is a way of counting the results of a relationship without loading them. [Source]


Eloquent global query scopes define constraints applicable to all queries on that model. [Source]


Laravel's str_plural helper returns the appropriate plural form of a string. [Source]


The toSql method returns the SQL query of a given Eloquent query. [Source]


The whole section on polymorphic relations was new to me. [Source]


In database migrations, create a unique combined index with unique; e.g. $table->unique(['user_id', 'favorited_id', 'favorited_type']);. [Source]


JW: "One of the downsides" of Eloquent is its tendency to hide the presence of multiple SQL queries when accessing relationships between models. [Source]


Global eager loading in an Eloquent model is possible by overriding the $with property. E.g.

protected $with = ['owner']



You can use model events to (among other things) delete related models when a model is deleted. E.g. in the boot method of a model:

static::deleting(function($thread) {



The method_field helper spoofs HTTP verbs in forms. E.g.

{{ method_field('DELETE') }}



Use @forelse and @empty to show messages when a collection of data to be looped through is empty. [Source]


The artisan make:policy command generates an empty policy class. The flag --model=Foo adds some boilerplate. [Source]


The @can and @cannot Blade directives check whether the logged in user can perform a given action. [Source]


To give a super admin permission to perform all actions, either use the before method on a policy, or to apply this to all policies use the Gate class in the boot method of AuthServiceProvider. E.g.:

Gate::before(function($user) {
  if ($user->name === 'super admin') return true;



Not Laravel specific, but to get the short name of a class (i.e. without the namespace), this can be done with the ReflectionClass method getShortName. E.g.:

$name = (new \ReflectionClass($thread))->getShortName();



You can move boot methods from specific models to traits they use with the function boot[TraitName] in the trait. E.g.:

protected static function bootRecordsActivity()



You can pass a closure to the groupBy method. [Source]


Chain the with method to a redirect response to flash data to the session. [Source]


Use the @includeIf Blade directive to only include a view if it exists. Inspired by (this video).


Use inline templates to use a Blade file (or other HTML) as a Vue component's template. [Source]


Use the v-cloak directive, in combination with a CSS rule like [v-cloak] { display: none; }, to hide a Vue component until it's loaded. [Source]


Use the appends property to add Eloquent attributes to a model's array or JSON representation. [Source]


Use the Eloquent fresh method to reload a model from the database. [Source]


For a model event (e.g. deleting) to fire, the model has to be deleted (or updated etc.), rather than building an SQL command with the query builder. I.e. this:

$this->favorites()->where($attributes)->get()->each(function($favorite) {

instead of




Higher order messages are "properties" to make performing tasks on collections more readable. E.g., using the each higher order message:




The Vue v-for directive can take a second argument that supplies the index of an item. E,g.:

<div v-for="(reply, index) in items"
  <reply :data="reply" @deleted="remove(index)"></reply>



Use Vue mixins for creating reusable functionality. [Source]


A Vue watcher can be used to perform some new function when a component's data changes. [Source]


In Vue, the .prevent event modifier will perform the equivalent of preventDefault(). E.g. @click.prevent. [Source]


increment and decrement are database query builder helpers to increment or decrement the value of a column. [Source]


To append an attribute to a single instance of an Eloquent model (rather than to every instance as in 41 above), use the append method. [Source]

Click here for Part 2, covering the second half of the series.