Skip to content

Commit 902b8c2

Browse files
committed
New tips for February 2023
1 parent b3ec03e commit 902b8c2

File tree

9 files changed

+176
-37
lines changed

9 files changed

+176
-37
lines changed

README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,21 @@ Or if you want the Chinese version:
2222
[中文版本](https://github.com/Lysice/laravel-tips-chinese/blob/master/README-zh.md)
2323

2424
---
25-
**Update 20 December 2022**: Currently there are **344 tips** divided into 14 sections.
25+
**Update 20 February 2023**: Currently there are **352 tips** divided into 14 sections.
2626

2727
## Table of contents
2828

29-
- [DB Models and Eloquent](db-models-and-eloquent.md) (94 tips)
30-
- [Models Relations](models-relations.md) (35 tips)
29+
- [DB Models and Eloquent](db-models-and-eloquent.md) (97 tips)
30+
- [Models Relations](models-relations.md) (36 tips)
3131
- [Migrations](migrations.md) (15 tips)
32-
- [Views](views.md) (19 tips)
32+
- [Views](views.md) (20 tips)
3333
- [Routing](routing.md) (33 tips)
3434
- [Validation](validation.md) (24 tips)
35-
- [Collections](collections.md) (9 tips)
36-
- [Auth](auth.md) (5 tips)
35+
- [Collections](collections.md) (8 tips)
36+
- [Auth](auth.md) (6 tips)
3737
- [Mail](mail.md) (7 tips)
38-
- [Artisan](artisan.md) (7 tips)
38+
- [Artisan](artisan.md) (9 tips)
3939
- [Factories](factories.md) (8 tips)
4040
- [Log and debug](log-and-debug.md) (8 tips)
4141
- [API](api.md) (9 tips)
42-
- [Other](other.md) (71 tips)
42+
- [Other](other.md) (72 tips)

artisan.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
⬆️ [Go to main menu](README.md#laravel-tips) ⬅️ [Previous (Mail)](mail.md) ➡️ [Next (Factories)](factories.md)
44

55
- [Artisan command parameters](#artisan-command-parameters)
6+
- [Execute a Closure after command runs without errors or has any errors](#execute-a-closure-after-command-runs-without-errors-or-has-any-errors)
7+
- [Run artisan commands on specific environments](#run-artisan-commands-on-specific-environments)
68
- [Maintenance Mode](#maintenance-mode)
79
- [Artisan command help](#artisan-command-help)
810
- [Exact Laravel version](#exact-laravel-version)
@@ -27,6 +29,34 @@ $name = $this->anticipate('What is your name?', ['Taylor', 'Dayle']);
2729
$name = $this->choice('What is your name?', ['Taylor', 'Dayle'], $defaultIndex);
2830
```
2931

32+
### Execute a Closure after command runs without errors or has any errors
33+
34+
With Laravel scheduler you can execute a Closure when a command runs without errors with the onSuccess() method and also when a command has any errors with the onFailure() method.
35+
36+
```php
37+
protected function schedule(Schedule $schedule)
38+
{
39+
$schedule->command('newsletter:send')
40+
->mondays()
41+
->onSuccess(fn () => resolve(SendNewsletterSlackNotification::class)->handle(true))
42+
->onFailure(fn () => resolve(SendNewsletterSlackNotification::class)->handle(false));
43+
}
44+
```
45+
46+
Tip given by [@wendell_adriel](https://twitter.com/wendell_adriel)
47+
48+
### Run artisan commands on specific environments
49+
50+
Take control of your Laravel scheduled commands. Run them on specific environments for ultimate flexibility.
51+
52+
```php
53+
$schedule->command('reports:send')
54+
->daily()
55+
->environments(['production', 'staging']);
56+
```
57+
58+
Tip given by [@LaraShout](https://twitter.com/LaraShout)
59+
3060
### Maintenance Mode
3161

3262
If you want to enable maintenance mode on your page, execute the down Artisan command:

auth.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
⬆️ [Go to main menu](README.md#laravel-tips) ⬅️ [Previous (Collections)](collections.md) ➡️ [Next (Mail)](mail.md)
44

55
- [Check Multiple Permissions at Once](#check-multiple-permissions-at-once)
6+
- [Authenticate users with more options](#authenticate-users-with-more-options)
67
- [More Events on User Registration](#more-events-on-user-registration)
78
- [Did you know about Auth::once()?](#did-you-know-about-authonce)
89
- [Change API Token on users password update](#change-api-token-on-users-password-update)
@@ -20,6 +21,24 @@ In addition to `@can` Blade directive, did you know you can check multiple permi
2021
@endcanany
2122
```
2223

24+
### Authenticate users with more options
25+
26+
If you only want to authenticate users that are also "activated", for example, it's as simple as passing an extra argument to `Auth::attempt()`.
27+
28+
No need for complex middleware or global scopes.
29+
30+
```php
31+
Auth::attempt(
32+
[
33+
...$request->only('email', 'password'),
34+
fn ($query) => $query->whereNotNull('activated_at')
35+
],
36+
$this->boolean('remember')
37+
);
38+
```
39+
40+
Tip given by [@LukeDowning19](https://twitter.com/LukeDowning19)
41+
2342
### More Events on User Registration
2443

2544
Want to perform some actions after new user registration? Head to `app/Providers/EventServiceProvider.php` and add more Listeners classes, and then in those classes implement `handle()` method with `$event->user` object
@@ -97,3 +116,4 @@ Gate::before(function (?User $user, $ability) {
97116
return $user->hasRole('Super Admin') ? true : null;
98117
});
99118
```
119+

collections.md

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
- [Multiple Collection Methods in a Row](#multiple-collection-methods-in-a-row)
88
- [Calculate Sum with Pagination](#calculate-sum-with-pagination)
99
- [Serial no in foreach loop with pagination](#serial-no-in-foreach-loop-with-pagination)
10-
- [Higher order collection methods](#higher-order-collection-methods)
1110
- [Higher order collection message](#higher-order-collection-message)
1211
- [Get an existing key or insert a value if it doesn't exist and return the value](#get-an-existing-key-or-insert-a-value-if-it-doesnt-exist-and-return-the-value)
1312
- [Static times method](#static-times-method)
@@ -90,27 +89,6 @@ We can use foreach collection items index as serial no (SL) in pagination.
9089

9190
it will solve the issue of next pages(?page=2&...) index count from continue.
9291

93-
### Higher order collection methods
94-
95-
Collections have higher order methods, this are methods that can be chained , like `groupBy()` , `map()` ... Giving you a fluid syntax. This example calculates the
96-
price per group of products on an offer.
97-
98-
```php
99-
$offer = [
100-
'name' => 'offer1',
101-
'lines' => [
102-
['group' => 1, 'price' => 10],
103-
['group' => 1, 'price' => 20],
104-
['group' => 2, 'price' => 30],
105-
['group' => 2, 'price' => 40],
106-
['group' => 3, 'price' => 50],
107-
['group' => 3, 'price' => 60]
108-
]
109-
];
110-
111-
$totalPerGroup = collect($offer['lines'])->groupBy('group')->map(fn($group) => $group->sum('price'));
112-
```
113-
11492
### Higher order collection message
11593

11694
Collections also provide support for "higher order messages", which are short-cuts for performing common actions on collections.

db-models-and-eloquent.md

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
- [You can write transaction-aware code](#you-can-write-transaction-aware-code)
1111
- [Eloquent scopes inside of other relationships](#eloquent-scopes-inside-of-other-relationships)
1212
- [New `rawValue()` method since Laravel 9.37](#new-rawvalue-method-since-laravel-937)
13+
- [Load data faster when the targeted value is an integer](#load-data-faster-when-the-targeted-value-is-an-integer)
14+
- [Load data completed between two timestamps](#load-data-completed-between-two-timestamps)
15+
- [Pass a raw query to order your results](#pass-a-raw-query-to-order-your-results)
1316
- [Eloquent where date methods](#eloquent-where-date-methods)
1417
- [Increments and decrements](#increments-and-decrements)
1518
- [No timestamp columns](#no-timestamp-columns)
@@ -241,7 +244,7 @@ class User extends Model
241244
static::created(function ($user) {
242245
// Will send the email only if the
243246
// transaction is committed
244-
DB::afterCommit(function () use ($user) {
247+
DB::afterCoommit(function () use ($user) {
245248
Mail::send(new WelcomeEmail($user));
246249
});
247250
});
@@ -291,6 +294,50 @@ $fullname = UserModel::where('id', $id)
291294

292295
Tip given by [@LoydRG](https://twitter.com/LoydRG/status/1587689148768567298)
293296

297+
### Load data faster when the targeted value is an integer
298+
299+
Instead of using the 𝘄𝗵𝗲𝗿𝗲𝗜𝗻() method to load a large range of data when the targeted value is an integer, use 𝘄𝗵𝗲𝗿𝗲𝗜𝗻𝘁𝗲𝗴𝗲𝗿𝗜𝗻𝗥𝗮𝘄() which is faster than 𝘄𝗵𝗲𝗿𝗲𝗜𝗻().
300+
301+
```php
302+
// instead of using whereIn
303+
Product::whereIn('id', range(1, 50))->get();
304+
305+
// use WhereIntegerInRaw method for faster loading
306+
Product::whereIntegerInRaw('id', range(1, 50))->get();
307+
```
308+
309+
Tip given by [@LaraShout](https://twitter.com/LaraShout)
310+
311+
### Load data completed between two timestamps
312+
313+
Use 𝘄𝗵𝗲𝗿𝗲𝗕𝗲𝘁𝘄𝗲𝗲𝗻 to load records between two timestamps, you can pass the fallback value using the null coalescing operator (??).
314+
315+
```php
316+
// Load tasks completed between two timestamps
317+
Task::whereBetween('completed_at', [
318+
$request->from ?? '2023-01-01',
319+
$request->to ?? today()->toDateTimeString(),
320+
]);
321+
```
322+
323+
Tip given by [@LaraShout](https://twitter.com/LaraShout)
324+
325+
### Pass a raw query to order your results
326+
327+
You can pass a raw query to order your results.
328+
329+
For example, sorting tasks by how long before the due date they were completed.
330+
331+
```php
332+
// Sort tasks by the task was completed before the due date
333+
$tasks = Task::query()
334+
->whereNotNull('completed_at')
335+
->oorderByRaw('due_at - completed_at DESC')
336+
->get();
337+
```
338+
339+
Tip given by [@cosmeescobedo](https://twitter.com/cosmeescobedo)
340+
294341
### Eloquent where date methods
295342

296343
In Eloquent, check the date with functions `whereDay()`, `whereMonth()`, `whereYear()`, `whereDate()` and `whereTime()`.
@@ -1134,11 +1181,11 @@ $post->author->name ?? ''
11341181
// But you can do it on Eloquent relationship level:
11351182
// this relation will return an empty App\Author model if no author is attached to the post
11361183
public function author() {
1137-
return $this->belongsTo('App\Author')->withDefault();
1184+
return $this->belongsTo(Author::class)->withDefault();
11381185
}
11391186
// or
11401187
public function author() {
1141-
return $this->belongsTo('App\Author')->withDefault([
1188+
return $this->belongsTo(Author::class)->withDefault([
11421189
'name' => 'Guest Author'
11431190
]);
11441191
}

migrations.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ Schema::create('posts', function (Blueprint $table) {
297297
$table->id();
298298
$table->string('title');
299299
$table->timestamp('added_at')->useCurrent();
300-
$table->timespamps();
300+
$table->timestamps();
301301
});
302302
```
303303

models-relations.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
- [OrderBy on Eloquent relationships](#orderby-on-eloquent-relationships)
66
- [Add where statement to Many-to-Many relation](#add-where-statement-to-many-to-many-relation)
7+
- [Get the newest (or oldest) item of another relation](#get-the-newest-or-oldest-item-of-another-relation)
78
- [Conditional relationships](#conditional-relationships)
89
- [Raw DB Queries: havingRaw()](#raw-db-queries-havingraw)
910
- [Eloquent has() deeper](#eloquent-has-deeper)
@@ -78,6 +79,28 @@ class Developer extends Model
7879

7980
Tip given by [@cosmeescobedo](https://twitter.com/cosmeescobedo/status/1582904416457269248)
8081

82+
### Get the newest (or oldest) item of another relation
83+
84+
Since Laravel 8.42, in an Eloquent model, you can define a relation that will get the newest (or oldest) item of another relation.
85+
86+
```php
87+
/**
88+
* Get the user's latest order.
89+
*/
90+
public function latestOrder()
91+
{
92+
return $this->hasOne(Order::class)->latestOfMany();
93+
}
94+
95+
/**
96+
* Get the user's oldest order.
97+
*/
98+
public function oldestOrder()
99+
{
100+
return $this->hasOne(Order::class)->oldestOfMany();
101+
}
102+
```
103+
81104
### Conditional relationships
82105

83106
If you notice that you use same relationship often with additional "where" condition, you can create a separate relationship method.

other.md

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
- [Schedule Laravel job based on time zone](#schedule-laravel-job-based-on-time-zone)
1313
- [Use assertModelMissing instead assertDatabaseMissing](#use-assertmodelmissing-instead-assertdatabasemissing)
1414
- [Various options to format diffForHumans()](#various-options-to-format-diffforhumans)
15+
- [Create custom disks at runtime](#create-custom-disks-at-runtime)
1516
- [When (NOT) to run "composer update"](#when-not-to-run-composer-update)
1617
- [Composer: Check for Newer Versions](#composer-check-for-newer-versions)
1718
- [Auto-Capitalize Translations](#auto-capitalize-translations)
@@ -270,6 +271,22 @@ $user->created_at->diffForHumans([
270271
```
271272
=> `"17h, 54m, 50s ago"`
272273

274+
### Create custom disks at runtime
275+
276+
Did you know that you can create custom disks at runtime without the need to have the config in your config/filesystems file?
277+
278+
This can be handy to manage files in custom paths without the need of adding them to the config.
279+
280+
```php
281+
$avatarDisk = Storage::build([
282+
'driver' => 'local',
283+
'root' => storage_path('app/avatars'),
284+
]);
285+
$avatarDisk->put('user_avatar.jpg', $image);
286+
```
287+
288+
Tip given by [@wendell_adriel](https://twitter.com/wendell_adriel/)
289+
273290
### When (NOT) to run "composer update"
274291

275292
Not so much about Laravel, but... Never run `composer update` on production live server, it's slow and will "break" repository. Always run `composer update` locally on your computer, commit new `composer.lock` to the repository, and run `composer install` on the live server.
@@ -527,7 +544,7 @@ If you want to see ALL results, you may go to the GitHub Laravel docs repository
527544

528545
### Filter route:list
529546

530-
New in Laravel 8.34: `php artisan route:list` gets additional flag `--except-path`, so you would filter out the routes you don't want to see. [See original PR](New in Laravel 8.34: `php artisan route:list` gets additional flag `--except-path`, so you would filter out the routes you don't want to see. [See original PR](https://github.com/laravel/framework/pull/36619))
547+
New in Laravel 8.34: `php artisan route:list` gets additional flag `--except-path`, so you would filter out the routes you don't want to see. [See original PR](https://github.com/laravel/framework/pull/36619)
531548

532549
### Blade directive for not repeating yourself
533550

@@ -735,7 +752,7 @@ class MigrationsTest extends TestCase
735752
$this->expectNotToPerformAssertions();
736753

737754

738-
Artisan::call('migrate:fresh', ['--path' => '/database/migrations/task1']);
755+
Artisan::call('migrate:fresh', ['--path' => '/database/migrations/task1']);
739756
}
740757
}
741758
```

views.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- [$loop variable in foreach](#loop-variable-in-foreach)
66
- [You can use Blade to generate more than HTML](#you-can-use-blade-to-generate-more-than-html)
77
- [Short attribute syntax for Blade Components](#short-attribute-syntax-for-blade-components)
8+
- [Share one variable with multiple views](#share-one-variable-with-multiple-views)
89
- [Does view file exist?](#does-view-file-exist)
910
- [Error code Blade pages](#error-code-blade-pages)
1011
- [View without controllers](#view-without-controllers)
@@ -74,6 +75,29 @@ Short syntax:
7475
<x-profile :$userId></x-profile>
7576
```
7677

78+
### Share one variable with multiple views
79+
80+
Have you ever needed to share one variable with multiple views in Laravel? Here's a simple solution for that.
81+
82+
```php
83+
use App\Models\Post;
84+
use Illuminate\Support\Facades\View;
85+
use Illuminate\Support\Facades\Schema;
86+
use Illuminate\Support\ServiceProvider;
87+
88+
class AppServiceProvider extends ServiceProvider
89+
{
90+
public function boot()
91+
{
92+
if (Schema::hasTable('posts')) {
93+
View::share('recentPosts', Post::latest()->take(3)->get());
94+
}
95+
}
96+
}
97+
```
98+
99+
Tip given by [@codewithdary](https://twitter.com/codewithdary)
100+
77101
### Does view file exist?
78102

79103
You can check if View file exists before actually loading it.
@@ -92,7 +116,7 @@ return view()->first(['custom.dashboard', 'dashboard'], $data);
92116

93117
### Error code Blade pages
94118

95-
If you want to create a specific error page for some HTTP code, like 500 - just create a blade file with this code as filename, in `resources/views/errors/500.blade.php`, or `403.blade.php` etc, and it will automatically be loaded in case of that error code.
119+
If you want to create a specific error page for some HTTP code, like 503 - just create a blade file with this code as filename, in `resources/views/errors/503.blade.php`, or `403.blade.php` etc, and it will automatically be loaded in case of that error code.
96120

97121
### View without controllers
98122

0 commit comments

Comments
 (0)