Skip to content

Commit 044a250

Browse files
Merge pull request #1 from liam-wiltshire/documentation-update
Add various bits of documentation
2 parents ee12cdf + 844d27a commit 044a250

File tree

3 files changed

+118
-1
lines changed

3 files changed

+118
-1
lines changed

CONTRIBUTING.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Contributing
2+
3+
This will be more fleshed out, in the coming weeks, but essentially:
4+
5+
1. Code should adhere to PSR-2 standards please
6+
2. Please include unit tests for any significant code changes
7+
3. Please ensure code changes do not break existing tests
8+
4. Changes that don't fit with the project goals may be rejected - if in doubt, ask first :-).

LICENSE.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2019 Liam Wiltshire
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,89 @@
1-
# laravel-jit-loader
1+
# liam-wiltshire/laravel-jit-loader
2+
3+
liam-wiltshire/laravel-jit-loader is an extension to the default Laravel Eloquent model to 'very lazy eager load' relationships.
4+
5+
# Very Lazy Eager Load?
6+
In order to avoid [N+1 issues](https://secure.phabricator.com/book/phabcontrib/article/n_plus_one/), you'd normally load your required relationships while building your collection:
7+
8+
```php
9+
$books = App\Book::with(['author', 'publisher'])->get();
10+
```
11+
12+
Or otherwise after the fact, but before use:
13+
14+
```php
15+
$books = App\Book::all();
16+
17+
if ($someCondition) {
18+
$books->load('author', 'publisher');
19+
}
20+
```
21+
22+
In some situations however, this may not be possible - perhaps front-end developers are able to make changes to templates without touching the code, or perhaps during development you know don't which relationships you'll need anyway.
23+
This change will track if your models belong to a collection, and if they do and a relationship is called that hasn't already been loaded, the relationship will be loaded across the whole collection just in time for use.
24+
25+
# Does This Work?
26+
Yes. At least, it does in our production Laravel app. It's also been tested against a (rather constructed) test, pulling out staff, companies and addresses - while this isn't a 'real life' representation, it should give an idea of what it can do:
27+
28+
```php
29+
public function handle()
30+
{
31+
//Count the number of queries
32+
$querycount = 0;
33+
DB::listen(function ($query) use (&$querycount) {
34+
$querycount++;
35+
});
36+
37+
$startTime = microtime(true);
38+
39+
40+
$staff = Staff::where('name', 'LIKE', 'E%')->orWhere('name', 'LIKE', 'P%')->get();
41+
42+
/**
43+
* @var Staff $st
44+
*/
45+
foreach ($staff as $st) {
46+
/**
47+
* @var Company $company
48+
*/
49+
$company = $st->company;
50+
echo "\n\nName: {$st->name}\n";
51+
echo "Company Name: {$company->name}\n";
52+
foreach ($company->address as $address) {
53+
echo "Addresses: {$address->address_1}, ";
54+
}
55+
}
56+
57+
$endTime = microtime(true);
58+
59+
echo "\n\n=========================\n\n";
60+
echo "Queries Run: {$querycount}\n";
61+
echo "Execution Time: " . ($endTime - $startTime) . "\n";
62+
echo "Memory:" . memory_get_peak_usage(true)/1024/1024 . "MiB";
63+
echo "\n\n";
64+
}
65+
```
66+
67+
Running this locally against a database with 200 companies, 1157 addresses and 39685 staff:
68+
69+
## Without JIT loading:
70+
Queries Run: 10739
71+
Execution Time: 16.058979034424
72+
Memory:68MiB
73+
74+
75+
## With JIT loading:
76+
Queries Run: 6
77+
Execution Time: 1.6715261936188
78+
Memory:26MiB
79+
80+
# Installation
81+
liam-wiltshire/laravel-jit-loader is available as a composer package:
82+
`composer require liam-wiltshire/laravel-jit-loader`
83+
84+
Once installed, have your models extend the `\LiamWiltshire\LaravelJitLoader\Model` class instead of the default eloquent model, and JIT loading will be automatically enabled.
85+
86+
# Limitations
87+
This is an early release based on specific use cases. At the moment the autoloading will only be used when the relationship is loaded like a property e.g. `$user->company->name` instead of `$user->company()->first()->name`. I am working on supporting relations loaded in alternate ways, however there is more complexity in that so there isn't a fixed timescale as of yet!
88+
89+
With any eager loading, a sufficiently large collection can cause memory issues. The JIT model specifies a threshold for autoloading. This is set to 6000 by default, but can be changed by overriding the `$autoloadThreshold` property on a model-by-model basis.

0 commit comments

Comments
 (0)