@@ -4,8 +4,12 @@ Entity relationships for CodeIgniter 4
44## Quick Start
55
661 . Install with Composer: ` > composer require tatter/relations `
7- 2 . Extend the model: ` class UserModel extends \Tatter\Relations\Model `
7+ 2 . Add the trait to your model: ` use \Tatter\Relations\Traits\ModelTrait `
883 . Load relations: ` $users = $userModel->with('groups')->findAll(); `
9+ 4 . Add the trait to your entity: ` use \Tatter\Relations\Traits\EntityTrait `
10+ 5 . Load relations: ` foreach ($user->groups as $group) `
11+
12+ (See also Examples at the bottom)
913
1014## Installation
1115
@@ -24,8 +28,7 @@ in the comments. If no config file is found in **app/Config** the library will u
2428
2529### Schemas
2630
27- All the functionality of the library lies in the specialized model and the generated
28- database schema. The schema is generated from
31+ All the functionality of the library relies on the generated database schema. The schema comes from
2932[ Tatter\Schemas] ( http://github.com/tattersoftware/codeigniter4-schemas ) and can be adjusted
3033based on your needs (see the ** Schemas** config file). If you want to use the auto-generated
3134schema your database will have follow conventional naming patterns for foreign keys and
@@ -34,17 +37,29 @@ for details.
3437
3538## Usage
3639
37- In order to take advantage of relationship loading you need your model to extend
38- ` Tatter\Relations\Model ` . This model extends the finders from CodeIgniter's core model and
39- injects related items that you define into the returned rows. Related items can be requested
40- by adding a ` $with ` property to your model:
40+ Relation loading is handled by traits that are added to their respective elements.
41+
42+ ### Eager/Model
43+
44+ ** ModelTrait** adds relation loading to your models by extending the default model ` find* `
45+ methods and injecting relations into the returned results. Because this happens at the model
46+ level, related items can be loaded ahead of time in batches ("eager loading").
47+
48+ Add the trait to your models:
49+
50+ use \Tatter\Relations\Traits\ModelTrait
51+
52+ Related items can be requested by adding a ` $with ` property to your model:
53+
4154```
4255 protected $with = 'groups';
4356 // or
4457 protected $with = ['groups', 'permissions'];
4558```
4659
4760... or by requesting it on-the-fly using the model ` with() ` method:
61+
62+
4863```
4964$users = $userModel->with('groups')->findAll();
5065foreach ($users as $userEntity)
@@ -53,8 +68,50 @@ foreach ($users as $userEntity)
5368...
5469```
5570
56- As you can see the related items are added directly to their corresponding object or array
57- returned from the primary model.
71+ As you can see the related items are added directly to their corresponding object (or array)
72+ returned from the framework's model.
73+
74+ ### Lazy/Entity
75+
76+ ** EntityTrait** adds relation loading to individual items by extending adding magic ` __get() `
77+ and ` __call() ` methods to check for matching database tables. Because this happens on each
78+ item, related items can be retrieved or updated on-the-fly ("lazy loading").
79+
80+ Add the trait and its necessary properties to your entities:
81+
82+ ```
83+ use \Tatter\Relations\Traits\EntityTrait
84+
85+ protected $table = 'users';
86+ protected $primaryKey = 'id';
87+ ```
88+
89+ Related items are available as faux properties:
90+
91+ ```
92+ $user = $userModel->find(1);
93+
94+ foreach ($user->groups as $group)
95+ {
96+ echo $group->name;
97+ }
98+ ```
99+
100+ ... and can also be updated directly from the entity:
101+
102+ ```
103+ $user->addGroup(3);
104+
105+ if ($user->hasGroups([1, 3]))
106+ {
107+ echo 'allowed!';
108+ }
109+
110+ $user->setGroups([]);
111+ ```
112+
113+ Available magic method verbs are: ` has ` , ` set ` , ` add ` , and ` remove ` , and are only applicable
114+ for "manyToMany" relationships.
58115
59116## Returned items
60117
@@ -74,13 +131,15 @@ echo $widget->name . " belongs to " . $widget->user->name;
74131
75132### Nesting
76133
77- ** Relations ** supports nested relation calls, but these can be resource intensive so may
134+ ** ModelTrait ** supports nested relation calls, but these can be resource intensive so may
78135be disabled by changing ` $allowNesting ` in the config. With nesting enabled, any related
79- items will alos load their related items:
136+ items will also load their related items (but not infinitely) :
80137```
81138/* Define your models */
82- class UserModel extends \Tatter\Relations\Model
139+ class UserModel
83140{
141+ use \Tatter\Relations\Traits\ModelTrait;
142+
84143 protected $table = 'users';
85144 protected $with = 'widgets';
86145...
@@ -101,14 +160,35 @@ foreach ($groups as $group)
101160
102161## Performance
103162
104- ** WARNING** Be aware that ** Relations** relies on a schema generated from the ** Schemas**
163+ * WARNING* : Be aware that ** Relations** relies on a schema generated from the ** Schemas**
105164library. While this process is relatively quick, it will cause a noticeable delay if a page
106165request initiates the load. The schema will attempt to cache to prevent this delay, but
107- if your cache is not configured correctly you * will* experience noticeable performance
108- degradation! The recommended approach is to have a cron job generate your schema regularly
166+ if your cache is not configured correctly you will likely experience noticeable performance
167+ degradation. The recommended approach is to have a cron job generate your schema regularly
109168so it never expires and no user will trigger the un-cached load, e.g.:
110169```
111- php spark schemas database model file -export cache
170+ php spark schemas
112171```
113172
114173See [ Tatter\Schemas] ( http://github.com/tattersoftware/codeigniter4-schemas ) for more details.
174+
175+ ### Eager or Lazy Loading
176+
177+ You are responsible for your application's performance! These tools are here to help, but
178+ they still allow dumb things.
179+
180+ Eager loading (via ** ModelTrait** ) can create a huge performance
181+ increase by consolidating what would normally be multiple database calls into one. However,
182+ the related items will take up additional memory and can cause other bottlenecks or script
183+ failures if used indiscriminately.
184+
185+ Lazy loading (via ** EntityTrait** ) makes it very easy to work with related items only when
186+ they are needed, and the magic functions keep your code clear and concise. However, each entity
187+ issues its own database call and can really start to slow down performance if used over
188+ over.
189+
190+ A good rule of thumb is to use ** ModelTrait** to preload relations that will be handled
191+ repeatedly (e.g. in loops) or that represent a very small or static dataset (e.g. a set of
192+ preference strings from 10 available). Use ** EntityTrait** to handle individual items, such
193+ as viewing a single user page, or when it is unlikely you will use relations for most of the
194+ items.
0 commit comments