1
0
Fork 0
mirror of https://github.com/archtechx/laravel-tips.git synced 2025-12-12 05:14:04 +00:00

initial commit

This commit is contained in:
Samuel Štancl 2021-04-06 18:27:18 +02:00
commit 1beb9dd34c
281 changed files with 56773 additions and 0 deletions

View file

@ -0,0 +1,14 @@
---
title: 'Avoid helper *classes*'
tweet_id: '1272822458563821568'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean2CnyWoAEZ3Ef.jpg'
created_at: 2021-04-06T16:07:28+00:00
slug: avoid-helper-classes
---
Sometimes people put helpers into a class.
Beware, it can get messy. This is a class with only static methods used as helper functions. It's usually better to put these methods into classes with related logic or just keep them as global functions.

View file

@ -0,0 +1,14 @@
---
title: 'Avoid queries in Blade when possible'
tweet_id: '1272826450559803392'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean7jvPWkAAp2_6.jpg'
created_at: 2021-04-06T16:07:36+00:00
slug: avoid-queries-in-blade-when-possible
---
Sometimes you may want to execute DB queries in blade. There are some ok use cases for this, such as in layout files.
But if it's a view returned by a controller, pass the data in the view data instead.

View file

@ -0,0 +1,12 @@
---
title: 'Be friends with your IDE'
tweet_id: '1272826441424613378'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean6t2ZXgAEiJMa.jpg'
created_at: 2021-04-06T16:07:34+00:00
slug: be-friends-with-your-ide
---
Install extensions, write annotations, use typehints. Your IDE will help you with getting your code working correctly, which lets you spend more energy on writing code that's also readable.

View file

@ -0,0 +1,12 @@
---
title: 'Closure validation rules are 🔥. They''re often better than creating a class just for a single use'
tweet_id: '1308085658095886336'
thread_slug: 1-rt-1-tip
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/EidAtSYXgAc-6tH.png'
created_at: 2021-04-06T16:07:41+00:00
slug: closure-validation-rules-are-theyre-often-better-than-creating-a-class-just-for-a-single-use
---
Create a class if it's used on multiple places or way too complex.

View file

@ -0,0 +1,16 @@
---
title: 'Comparing changes on ''saving'' using:'
tweet_id: '1308113281018728450'
thread_slug: 1-rt-1-tip
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/EidZs1IWAAUgH0m.png'
created_at: 2021-04-06T16:07:44+00:00
slug: comparing-changes-on-saving-using
---
$model->getOriginal()
in Eloquent event listeners can be very useful.
One such use case is checking whether an order is locked. If it is, the only write action we permit is unlocking it. Only then can changes be made.

View file

@ -0,0 +1,16 @@
---
title: 'Consider single-action controllers'
tweet_id: '1272826438891298816'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean6Sn9XkAA-WKS.png'
created_at: 2021-04-06T16:07:34+00:00
slug: consider-single-action-controllers
---
If you have a complex route action, consider moving it to a separate controller.
For OrderController::create, you'd create CreateOrderController.
Another solution is to move that logic to an action class — do what works best in your case.

View file

@ -0,0 +1,14 @@
---
title: 'Consider using form requests'
tweet_id: '1272822452201144321'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean0kWgXgAAcOXm.jpg'
created_at: 2021-04-06T16:07:26+00:00
slug: consider-using-form-requests
---
They're a great place to hide complex validation logic.
But beware of exactly that — hiding things. When your validation logic is simple, there's nothing wrong with doing it in the controller. Moving it to a form request makes it less explicit

View file

@ -0,0 +1,14 @@
---
title: 'Consider using helpers instead of facades. They can clean things up'
tweet_id: '1272826446717870081'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean7QGBXYAEt_l2.jpg'
created_at: 2021-04-06T16:07:35+00:00
slug: consider-using-helpers-instead-of-facades-they-can-clean-things-up
---
This is largely a matter of personal preference, but calling a global function instead of having to import a class and statically call a method feels nicer to me.
Bonus points for session('key') syntax.

View file

@ -0,0 +1,14 @@
---
title: 'Context matters'
tweet_id: '1272826465378357251'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean8vC0WAAEomIq.jpg'
created_at: 2021-04-06T16:07:38+00:00
slug: context-matters
---
Above I said that moving business logic to action/service classes is good. But context matters
Here's code design advice from a popular "Laravel best practices" repo. There's absolutely no reason to put a 3-line check into a class. That's just overengineered

View file

@ -0,0 +1,14 @@
---
title: 'Create action classes'
tweet_id: '1272822450137546753'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean0gvIWsAAIfxK.jpg'
created_at: 2021-04-06T16:07:26+00:00
slug: create-action-classes
---
Let's expand on the previous example. Sometimes, creating a class for a single action can clean things up.
Models should encapsulate the business logic related to them, but they shouldn't be too big.

View file

@ -0,0 +1,12 @@
---
title: 'Create custom Blade directives for business logic'
tweet_id: '1272826448810737670'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean7bYSXkAIwDIR.png'
created_at: 2021-04-06T16:07:35+00:00
slug: create-custom-blade-directives-for-business-logic
---
You can make your Blade templates more expressive by creating custom directives. For example, rather than checking if the user has the admin role, you could use @admin.

View file

@ -0,0 +1,14 @@
---
title: 'Create fluent objects'
tweet_id: '1272822468219109377'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean3zqXWAAASnOP.png'
created_at: 2021-04-06T16:07:29+00:00
slug: create-fluent-objects
---
You can also create objects with fluent APIs. Gradually add data by with separate calls, and only require the absolute minimum in the constructor.
Each method will return $this, so you can stop at any call.

View file

@ -0,0 +1,12 @@
---
title: 'Create helper functions'
tweet_id: '1272822457011970048'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean1ow4WoAAFjoT.jpg'
created_at: 2021-04-06T16:07:27+00:00
slug: create-helper-functions
---
If you repeat some code a lot, consider if extracting it to a helper function would make the code cleaner.

View file

@ -0,0 +1,14 @@
---
title: 'Create model methods for business logic'
tweet_id: '1272822448145272832'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean0WGiWAAAg4cu.jpg'
created_at: 2021-04-06T16:07:25+00:00
slug: create-model-methods-for-business-logic
---
Your controllers should be simple. They should say things like "create invoice for order". They shouldn't be concerned with the details of how your database is structured.
Leave that to the model.

View file

@ -0,0 +1,14 @@
---
title: 'Create query scopes for complex where()s'
tweet_id: '1272826431609933825'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean5ymtXgAEvlxm.jpg'
created_at: 2021-04-06T16:07:32+00:00
slug: create-query-scopes-for-complex-wheres
---
Rather than writing complex where() clauses, create query scopes with expressive names.
This will make your e.g. controllers have to know less about the database structure and your code will be cleaner.

View file

@ -0,0 +1,15 @@
---
title: 'Create single-use Blade includes'
tweet_id: '1272826427902234625'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images: { }
created_at: 2021-04-06T16:07:31+00:00
slug: create-single-use-blade-includes
---
Similar to single-use traits.
This tactic is great when you have a very long template and you want to make it more manageable.
There's nothing wrong with @including headers and footers in layouts, or things like complex forms in page views.

View file

@ -0,0 +1,14 @@
---
title: 'Create single-use traits'
tweet_id: '1272822478260363265'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean5BnEWkAEPUTe.jpg'
created_at: 2021-04-06T16:07:31+00:00
slug: create-single-use-traits
---
Adding methods to classes where they belong is cleaner than creating action classes for everything, but it can make the classes grow big
Consider using traits. They're meant *primarily* for code reuse, but there's nothing wrong with single-use traits

View file

@ -0,0 +1,14 @@
---
title: 'Create variables when they improve readability'
tweet_id: '1272822446278750208'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean0HJwWAAAZkDR.png'
created_at: 2021-04-06T16:07:24+00:00
slug: create-variables-when-they-improve-readability
---
The opposite of the previous tip. Sometimes the value comes from a complex call and as such, creating a variable improves readability & removes the need for a comment.
Remember that context matters & your end goal is readability

View file

@ -0,0 +1,13 @@
---
title: 'Dedicate a weekend towards learning proper OOP'
tweet_id: '1272822460631539712'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images: { }
created_at: 2021-04-06T16:07:28+00:00
slug: dedicate-a-weekend-towards-learning-proper-oop
---
Know the difference between static/instance methods & variables and private/protected/public visibility. Also learn how Laravel uses magic methods.
You don't need this as a beginner, but as your code grows, it's crucial.

View file

@ -0,0 +1,10 @@
---
title: 'Don''t create variables when you can just pass the value directly'
tweet_id: '1272822444621991937'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Eanz9WJWkAAeoT2.jpg'
created_at: 2021-04-06T16:07:24+00:00
slug: dont-create-variables-when-you-can-just-pass-the-value-directly
---

View file

@ -0,0 +1,14 @@
---
title: 'Don''t just write procedural code in classes'
tweet_id: '1272822462040899584'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean2u-YX0AEmwEd.jpg'
created_at: 2021-04-06T16:07:28+00:00
slug: dont-just-write-procedural-code-in-classes
---
This ties the previous tweet with the other tips here. OOP exists to make your code more readable, use it. Don't just write 400 line long procedural code in controller actions.
Here's code from my first Laravel project 😬

View file

@ -0,0 +1,14 @@
---
title: 'Don''t split lines at random places, but don''t make them too long either'
tweet_id: '1272822442990473216'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Eanz0jnXsAAvkv1.jpg'
created_at: 2021-04-06T16:07:23+00:00
slug: dont-split-lines-at-random-places-but-dont-make-them-too-long-either
---
Opening an array with [ and indenting the values tends to work well. Same with long function parameter values.
Other good places to split lines are chained calls and closures.

View file

@ -0,0 +1,14 @@
---
title: 'Don''t use a controller namespace'
tweet_id: '1272826437167468544'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean6NFJX0AAfiXT.png'
created_at: 2021-04-06T16:07:33+00:00
slug: dont-use-a-controller-namespace
---
Instead of writing controller actions like PostController@index, use the callable array syntax [PostController::class, 'index'].
You will be able to navigate to the class by clicking PostController.

View file

@ -0,0 +1,16 @@
---
title: 'Don''t use abbreviations'
tweet_id: '1272822472329572355'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean4TBBXgAAMab3.png'
created_at: 2021-04-06T16:07:30+00:00
slug: dont-use-abbreviations
---
Don't think that long variable/method names are wrong. They're not. They're expressive.
Better to call a longer method than a short one and check the docblock to understand what it does
Same with variables. Don't use nonsense 3-letters abbreviations

View file

@ -0,0 +1,14 @@
---
title: 'Don''t use model methods to retrieve data'
tweet_id: '1272826433417752576'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean58GjWAAAgqLq.jpg'
created_at: 2021-04-06T16:07:32+00:00
slug: dont-use-model-methods-to-retrieve-data
---
If you want to retrieve some data from a model, create an accessor.
Keep methods for things that *change* the model in some way.

View file

@ -0,0 +1,12 @@
---
title: 'Eloquent listeners are awesome'
tweet_id: '1308114698299154433'
thread_slug: 1-rt-1-tip
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/EidaLtrXcAU0nIG.png'
created_at: 2021-04-06T16:07:45+00:00
slug: eloquent-listeners-are-awesome
---
Example: Default value set on creation.

View file

@ -0,0 +1,14 @@
---
title: 'Example: Checking a parent relationship for some things'
tweet_id: '1308114701415571457'
thread_slug: 1-rt-1-tip
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/EidbX_UWAAMeB6-.png'
created_at: 2021-04-06T16:07:45+00:00
slug: example-checking-a-parent-relationship-for-some-things
---
Such as, checking if an Order is locked inside an OrderProduct.
OrderProducts cannot be added to/changed in a locked order.

View file

@ -0,0 +1,10 @@
---
title: 'Example: Deleting associated files on deletion'
tweet_id: '1308114699913961472'
thread_slug: 1-rt-1-tip
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/EidbEGZXYAA6q3G.png'
created_at: 2021-04-06T16:07:45+00:00
slug: example-deleting-associated-files-on-deletion
---

View file

@ -0,0 +1,12 @@
---
title: 'Extract methods'
tweet_id: '1272822455393026049'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean1UORWkAE4UDD.jpg'
created_at: 2021-04-06T16:07:27+00:00
slug: extract-methods
---
If some method is too long or complex, and it's hard to understand what exactly is happening, split the logic into multiple methods.

View file

@ -0,0 +1,13 @@
---
title: 'Have a single source of truth for validation rules'
tweet_id: '1272826456960315392'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images: { }
created_at: 2021-04-06T16:07:37+00:00
slug: have-a-single-source-of-truth-for-validation-rules
---
If you validate some resource's attributes on multiple places, you definitely want to centralize these validation rules, so that you don't change them in one place but forget about the other places.
https://twitter.com/LiamHammett/status/1260252814158282752

View file

@ -0,0 +1,16 @@
---
title: 'Here''s another example of the Model state stuff mentioned above'
tweet_id: '1308088600278560768'
thread_slug: 1-rt-1-tip
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/EidDSDcXYAA_7XD.jpg'
created_at: 2021-04-06T16:07:42+00:00
slug: heres-another-example-of-the-model-state-stuff-mentioned-above
---
Except...
It's multi-tenant!
Tip 7: It's incredibly easy to use http://tenancyforlaravel.com with Tinker 😎

View file

@ -0,0 +1,11 @@
---
title: 'If you didn''t know, @LaravelLivewire now triggers "updated" and "updating" hooks for nested properties, which works with both array and model properties!'
tweet_id: '1307716271904096262'
thread_slug: 1-rt-1-tip
author_username: LiamHammett
images:
- 'https://pbs.twimg.com/media/EiXw7FcXYAEGzFy.jpg'
- 'https://pbs.twimg.com/media/EiXw7h3WAAEjT9F.jpg'
created_at: 2021-04-06T16:07:48+00:00
slug: if-you-didnt-know-at-laravellivewire-now-triggers-updated-and-updating-hooks-for-nested-properties-which-works-with-both-array-and-model-properties
---

View file

@ -0,0 +1,14 @@
---
title: 'If you don''t like the "double indentation" of Vue data(), you can use arrow functions'
tweet_id: '1285486044561969154'
thread_slug: 1-rt-1-tip
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Edb2vN0XoAEnunt.png'
- 'https://pbs.twimg.com/media/Edb2vO8WoAAAcdX.png'
created_at: 2021-04-06T16:07:42+00:00
slug: if-you-dont-like-the-double-indentation-of-vue-data-you-can-use-arrow-functions
---
Left: double nesting
Right: arrow function

View file

@ -0,0 +1,13 @@
---
title: 'If you want to identify teams, workspaces, etc by path, you don''t have to pass the team ID to every route'
tweet_id: '1308096302530600963'
thread_slug: 1-rt-1-tip
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/EidKFFnX0AEEjwr.png'
- 'https://pbs.twimg.com/media/EidKYlkWoAAWkLD.png'
created_at: 2021-04-06T16:07:43+00:00
slug: if-you-want-to-identify-teams-workspaces-etc-by-path-you-dont-have-to-pass-the-team-id-to-every-route
---
In the example below, the value reaches the middleware, where you can do some stuff, and then is REMOVED from the route parameters before being passed to the action.

View file

@ -0,0 +1,14 @@
---
title: 'If you''re debugging your app and you''d like to examine more things - e.g. the stack trace, executed queries, app context, '
tweet_id: '1308109980504133633'
thread_slug: 1-rt-1-tip
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/EidXEVXXgAofRdr.jpg'
created_at: 2021-04-06T16:07:44+00:00
slug: if-youre-debugging-your-app-and-youd-like-to-examine-more-things-eg-the-stack-trace-executed-queries-app-context
---
You can use ddd() instead of dd().
I tend to forget about this one, but it's super useful.

View file

@ -0,0 +1,12 @@
---
title: 'Import namespaces instead of using aliases'
tweet_id: '1272826429483495424'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean5otqXYAA4QPR.png'
created_at: 2021-04-06T16:07:31+00:00
slug: import-namespaces-instead-of-using-aliases
---
Sometimes you may have multiple classes with the same name. Rather than importing them with an alias, import the namespaces.

View file

@ -0,0 +1,12 @@
---
title: 'Instead of writing repetitive `else if` statements, use an array to look up the wanted value based on the key you have'
tweet_id: '1272822439689555969'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/EanzWiHXsAAhshs.jpg'
created_at: 2021-04-06T16:07:22+00:00
slug: instead-of-writing-repetitive-else-if-statements-use-an-array-to-look-up-the-wanted-value-based-on-the-key-you-have
---
The code will be cleaner & more readable and you will see understandable exceptions if something goes wrong. No half-passing edge cases.

View file

@ -0,0 +1,13 @@
---
title: 'It''s about the *micro*'
tweet_id: '1272822438406094848'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images: { }
created_at: 2021-04-06T16:07:22+00:00
slug: its-about-the-micro
---
Using some "macro" philosophy for structuring your code, like hexagonal architecture or DDD won't save you.
A clean codebase is the result of constant good decisions at the micro level.

View file

@ -0,0 +1,18 @@
---
title: 'Laravel migrations have a very nice syntax for foreign keys'
tweet_id: '1308126491188883463'
thread_slug: 1-rt-1-tip
author_username: samuelstancl
images: { }
created_at: 2021-04-06T16:07:46+00:00
slug: laravel-migrations-have-a-very-nice-syntax-for-foreign-keys
---
I didn't know about this for so long.
Instead of:
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
You do:
$table->foreignId('user_id')->constrained();

View file

@ -0,0 +1,12 @@
---
title: 'Laravel Nova lets you show different resources/tools/cards/... based on an if check'
tweet_id: '1308084774586773510'
thread_slug: 1-rt-1-tip
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/EidABmBXcAAto9_.png'
created_at: 2021-04-06T16:07:41+00:00
slug: laravel-nova-lets-you-show-different-resourcestoolscards-based-on-an-if-check
---
Extremely handy when you have multiple admin panels in a single app.

View file

@ -0,0 +1,16 @@
---
title: 'Laravel Telescope is great for so many things'
tweet_id: '1308094765544734720'
thread_slug: 1-rt-1-tip
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/EidI3vCXgAIOCvY.png'
created_at: 2021-04-06T16:07:43+00:00
slug: laravel-telescope-is-great-for-so-many-things
---
One of them is examining sent emails ✉️
You usually don't need a service like Mailtrap. Just use the `log` mail driver and install Telescope.
(image stolen from the internet)

View file

@ -0,0 +1,14 @@
---
title: 'People underutilize the exception handler'
tweet_id: '1308082889561604102'
thread_slug: 1-rt-1-tip
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Eic5sfxWAAY2ym2.png'
created_at: 2021-04-06T16:07:39+00:00
slug: people-underutilize-the-exception-handler
---
You can tell the app what response to return when a specific exception is encountered.
This is the simplest example. There's many more use cases.

View file

@ -0,0 +1,14 @@
---
title: 'Relevant for people building packages 📦'
tweet_id: '1308086649184751619'
thread_slug: 1-rt-1-tip
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/EidBy75XsA4CZGx.jpg'
created_at: 2021-04-06T16:07:41+00:00
slug: relevant-for-people-building-packages
---
It's IMO better to use static properties and have "self-contained" behavior & configuration. Than to have a billion config keys. Especially when building large packages.
Makes the package more extensible, by consisting of atomic parts

View file

@ -0,0 +1,12 @@
---
title: 'There''s great value in understanding how object state of Models works. This is mostly relevant in (Feature) tests because they touch many parts of your codebase in one PHP/Laravel App state'
tweet_id: '1308082893865005068'
thread_slug: 1-rt-1-tip
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Eic9xP2XsAoo8ay.png'
created_at: 2021-04-06T16:07:40+00:00
slug: theres-great-value-in-understanding-how-object-state-of-models-works-this-is-mostly-relevant-in-feature-tests-because-they-touch-many-parts-of-your-codebase-in-one-phplaravel-app-state
---
For example, use $model->is($anotherModel) to check if they refer to the same row.

View file

@ -0,0 +1,16 @@
---
title: 'This one is less obscure'
tweet_id: '1308136547217281026'
thread_slug: 1-rt-1-tip
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/EidvI20XcAA7MGY.png'
created_at: 2021-04-06T16:07:48+00:00
slug: this-one-is-less-obscure
---
The $loop variable.
It greatly complements Tailwind-styled tables.
Striped tables done easily 🎉

View file

@ -0,0 +1,14 @@
---
title: 'This won''t fit into one tweet but there''s so much cool stuff you can do with Eloquent'
tweet_id: '1308134105389953024'
thread_slug: 1-rt-1-tip
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Eidq5A3XsAAM9lA.png'
created_at: 2021-04-06T16:07:46+00:00
slug: this-wont-fit-into-one-tweet-but-theres-so-much-cool-stuff-you-can-do-with-eloquent
---
You DON'T have to go raw SQL when you hit a performance issue with Eloquent. There's so many "secret" techniques.
Example: You can create scopes to add specific selects to your queries.

View file

@ -0,0 +1,12 @@
---
title: 'Try to avoid unnecessary nesting by returning a value early'
tweet_id: '1272822441392377856'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/EanzmPwXYAAoH2A.jpg'
created_at: 2021-04-06T16:07:23+00:00
slug: try-to-avoid-unnecessary-nesting-by-returning-a-value-early
---
Too much nesting & else statements tend to make code harder to read.

View file

@ -0,0 +1,12 @@
---
title: 'Use collections when they can clean up your code'
tweet_id: '1272826458667442176'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean8WekXkAEafMW.png'
created_at: 2021-04-06T16:07:37+00:00
slug: use-collections-when-they-can-clean-up-your-code
---
Don't turn all arrays into collections just because Laravel offers them, but DO turn arrays into collections when you can make use of collection syntax to clean up your code.

View file

@ -0,0 +1,12 @@
---
title: 'Use custom collections'
tweet_id: '1272822470656045057'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean3-8QXYAAmi7V.jpg'
created_at: 2021-04-06T16:07:30+00:00
slug: use-custom-collections
---
Creating custom collections can be a great way to achieve more expressive syntax. Consider this example with order totals.

View file

@ -0,0 +1,12 @@
---
title: 'Use custom config files'
tweet_id: '1272826435254845441'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean6FxnXkAAXDsl.png'
created_at: 2021-04-06T16:07:33+00:00
slug: use-custom-config-files
---
You can store things like "results per page" in config files. Don't add them to the app config file though. Create your own. In my e-commerce project, I use config/shop.php.

View file

@ -0,0 +1,14 @@
---
title: 'Use Data Transfer Objects (DTOs)'
tweet_id: '1272822466528845825'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean3uMaWAAApBhb.jpg'
created_at: 2021-04-06T16:07:29+00:00
slug: use-data-transfer-objects-dtos
---
Rather than passing a huge amount of arguments in a specific order, consider creating an object with properties to store this data.
Bonus points if you can find that some behavior can be moved into to this object.

View file

@ -0,0 +1,16 @@
---
title: 'Use docblocks only when they clarify things'
tweet_id: '1272826454301163520'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean8DcIXkAESZ_P.jpg'
created_at: 2021-04-06T16:07:37+00:00
slug: use-docblocks-only-when-they-clarify-things
---
Many people will disagree with this, because they do it. But it makes no sense.
There's no point in using docblocks when they don't give any extra information. If the typehint is enough, don't add a docblock.
That's just noise.

View file

@ -0,0 +1,14 @@
---
title: 'Use events'
tweet_id: '1272822453753036801'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean07-jXkAErgaL.jpg'
created_at: 2021-04-06T16:07:26+00:00
slug: use-events
---
Consider offloading some logic from controllers to events. For example, when creating models.
The benefit is that creating these models will work the same everywhere (controllers, jobs, ...) and the controller has one less worry about the details of the DB schema

View file

@ -0,0 +1,14 @@
---
title: 'Use expressive names for methods'
tweet_id: '1272822475957645312'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean4xcqWAAUsjdG.png'
created_at: 2021-04-06T16:07:30+00:00
slug: use-expressive-names-for-methods
---
Rather than thinking "what can this object do", think about "what can be done with this object". Exceptions apply, such as with action classes, but this is a good rule of thumb.
https://www.youtube.com/watch?v=dfgtKb-VpRk

View file

@ -0,0 +1,12 @@
---
title: 'Use short operators'
tweet_id: '1272826443630817281'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean63YeXQAABhBd.jpg'
created_at: 2021-04-06T16:07:34+00:00
slug: use-short-operators
---
PHP has many great operators that can replace ugly if checks. Memorize them.

View file

@ -0,0 +1,14 @@
---
title: 'Use strict comparison'
tweet_id: '1272826452652810240'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean722QXgAENwmW.jpg'
created_at: 2021-04-06T16:07:36+00:00
slug: use-strict-comparison
---
ALWAYS use strict comparison (=== and !==). If needed, cast things go the correct type before comparing. Better than weird == results
Also consider enabling strict types in your code. This will prevent passing variables of wrong data types to functions

View file

@ -0,0 +1,12 @@
---
title: 'Wanna update a set of Eloquent models and have the change updated in the database and in your in-memory instances, but don''t wanna incur a database query for *each* model?'
tweet_id: '1253524892055560193'
thread_slug: 1-rt-1-tip
author_username: timacdonald87
images:
- 'https://pbs.twimg.com/media/EWVoC3jVcAEg0JX.jpg'
created_at: 2021-04-06T16:07:49+00:00
slug: wanna-update-a-set-of-eloquent-models-and-have-the-change-updated-in-the-database-and-in-your-in-memory-instances-but-dont-wanna-incur-a-database-query-for-each-model
---
Custom collections got you sorted. Love these methods.

View file

@ -0,0 +1,14 @@
---
title: 'When a relationship is already loaded and "cached" on the model instance, you''ll have to refresh it'
tweet_id: '1308084124947820554'
thread_slug: 1-rt-1-tip
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Eic_JawXgAAEbYL.png'
created_at: 2021-04-06T16:07:40+00:00
slug: when-a-relationship-is-already-loaded-and-cached-on-the-model-instance-youll-have-to-refresh-it
---
`$domain->refresh();` to refresh its attributes
`$tenant->load('primary_domain');` to update the `primary_domain` relationship on the $tenant instance

View file

@ -0,0 +1,12 @@
---
title: 'When I''m converting data into a different structure, one thing I like to do is annotate how the structure looks at each point of the process'
tweet_id: '1308823625194233867'
thread_slug: 1-rt-1-tip
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/EinfW11XgAE0y7W.jpg'
created_at: 2021-04-06T16:07:49+00:00
slug: when-im-converting-data-into-a-different-structure-one-thing-i-like-to-do-is-annotate-how-the-structure-looks-at-each-point-of-the-process
---
I developed this habit when I was building a lot of data conversion scripts in Python, but it's 100% applicable in PHP as well.

View file

@ -0,0 +1,12 @@
---
title: 'Write functional code when it benefits you'
tweet_id: '1272826462031286272'
thread_slug: laravel-clean-code-tactics
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Ean8cQUWoAEjdO3.jpg'
created_at: 2021-04-06T16:07:38+00:00
slug: write-functional-code-when-it-benefits-you
---
Functional code can both clean things up and make them impossible to understand. Refactor common loops into functional calls, but don't write stupidly complex reduce()s just to avoid writing a loop. There's a use case for both.

View file

@ -0,0 +1,12 @@
---
title: 'Yesterday in my @LaraconOnline talk I explained how to use the query builder when() method to handle complex sorting'
tweet_id: '1233017064492761088'
thread_slug: 1-rt-1-tip
author_username: reinink
images:
- 'https://pbs.twimg.com/media/ERyNRSIX0AEjjWo.jpg'
created_at: 2021-04-06T16:07:49+00:00
slug: yesterday-in-my-at-laracononline-talk-i-explained-how-to-use-the-query-builder-when-method-to-handle-complex-sorting
---
What you may not realize is that the when() method also accepts a second callback for the falsy case. This is really helpful for setting a sort default. 🤩

View file

@ -0,0 +1,12 @@
---
title: 'You can add a tags() method to a job. Anything you return from this method will be displayed in Horizon'
tweet_id: '1308134110595084288'
thread_slug: 1-rt-1-tip
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/EidtAYaXkAEjAl-.jpg'
created_at: 2021-04-06T16:07:47+00:00
slug: you-can-add-a-tags-method-to-a-job-anything-you-return-from-this-method-will-be-displayed-in-horizon
---
Very useful if you want to tag jobs with things like the user/tenant id.

View file

@ -0,0 +1,12 @@
---
title: 'You can create dynamic relationships — this relationship is based on a column that''s added using a subquery, in a scope'
tweet_id: '1308134107118022666'
thread_slug: 1-rt-1-tip
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/EidrdqwWkAIy4oN.png'
created_at: 2021-04-06T16:07:47+00:00
slug: you-can-create-dynamic-relationships-this-relationship-is-based-on-a-column-thats-added-using-a-subquery-in-a-scope
---
And so much more.

View file

@ -0,0 +1,12 @@
---
title: 'You can explicitly bind objects to routes. You don''t have to use route model binding only. Custom objects work perfectly well too'
tweet_id: '1308140146374696962'
thread_slug: 1-rt-1-tip
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/EidyDmfWsAI14-C.png'
created_at: 2021-04-06T16:07:48+00:00
slug: you-can-explicitly-bind-objects-to-routes-you-dont-have-to-use-route-model-binding-only-custom-objects-work-perfectly-well-too
---
This example is from Tenancy v2 when we had an ActiveRecord-style custom Tenant object.

View file

@ -0,0 +1,12 @@
---
title: 'You can return "false" from a -ing() Eloquent event listener (creating, updating, saving, deleting) to cancel the action'
tweet_id: '1308127034565066766'
thread_slug: 1-rt-1-tip
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Eidmle3WoAI72Yk.png'
created_at: 2021-04-06T16:07:46+00:00
slug: you-can-return-false-from-a-ing-eloquent-event-listener-creating-updating-saving-deleting-to-cancel-the-action
---
This is similar to how I was throwing an exception based on certain things in the example with order locking.

View file

@ -0,0 +1,12 @@
---
title: 'You can return Mailables as responses from controllers. It will show the rendered version in the browser'
tweet_id: '1308082892162162690'
thread_slug: 1-rt-1-tip
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/Eic6iydX0AgLupY.png'
created_at: 2021-04-06T16:07:40+00:00
slug: you-can-return-mailables-as-responses-from-controllers-it-will-show-the-rendered-version-in-the-browser
---
Great for debugging/tweaking the design.

View file

@ -0,0 +1,14 @@
---
title: 'You can use where{X}and{Y}() in Eloquent'
tweet_id: '1308100321164619777'
thread_slug: 1-rt-1-tip
author_username: samuelstancl
images:
- 'https://pbs.twimg.com/media/EidOOuTXYAYMtI9.png'
created_at: 2021-04-06T16:07:43+00:00
slug: you-can-use-wherexandy-in-eloquent
---
Not recommended in most cases, but interesting.
(image stolen from the internet)