Welcome Guest, Not a member yet? Register   Sign In
Roster: Relation Name Lookup
#1

Hi all- I have some "dynamite" for you: small package, big impact! "Roster" solves a common, niche problem in an elegant way: quick access to display names for entity relations without requiring database lookup.
Tatter\Roster
Bulk name lookup for database relations in CodeIgniter 4
Packagist: https://packagist.org/packages/tatter/roster
GitHub: https://github.com/tattersoftware/codeigniter4-roster

An example to demonstrate how it works... You are developing a blog. At the bottom of every post is a comments section where logged in users may post replies. In order to display the user names next to each comment you need to cross-reference your "comments" table with the "users" table. You can:
  • Query the database with a JOIN to get all the info in one transaction, then parse it out later
  • Use an Object Relation Mapping (ORM) solution that makes entities "aware" of their related components
  • Load all the relevant users separately in the Controller then link them together
  • All of the above come with a performance cost, so you will need to include a way to cache the result so it does not affect every page.
Enter `Tatter\Roster`. A Roster class is a pre-defined mapping of table IDs to their "display name". The Roster service handles all the loading, lookup, and caching for you so you can be assured of the best performance for the least code.

Here's what your Roster looks like for Users, in app/Rosters/UserRoster.php:
PHP Code:
namespace App\Rosters;

use 
App\Models\UserModel;
use 
Tatter\Roster\ModelRoster;

class 
UserRoster extends ModelRoster
{
protected 
$modelName UserModel::class;
protected 
$field    'username';


The Roster Service handles locating your Roster and matching the ID, so you can use it inline right in your HTML:
Code:
<?php foreach ($comments as $comment): ?>
<div class="comment">
    <blockquote><?= $comment->content ?></blockquote>
    <div class="comment-footer">
        Commented by <?= service('roster')->user($comment->user_id) ?>
    </div>
</div>
<?php endforeach; ?>


That's all! As always check out the docs, give it a try, and send over any feedback you have.
Reply
#2

Thanks, will check it out later.
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply
#3

Thank you its great feature
Enlightenment  Is  Freedom
Reply
#4

This looks interesting and useful, but isn't it a little bit over engineered just to cache a key/value?
CodeIgniter 4 tutorials (EN/FR) - https://includebeer.com
/*** NO support in private message - Use the forum! ***/
Reply
#5

> isn't it a little bit over engineered

I suppose some may feel so. I tend to use libraries like project-level traits: reusable components to prevent duplicating code. In this case the concept was developed on a project using Firestore (NoSQL) where joins are not possible so looking up a single field for related items can be very costly. The flip side is that bulk reads of subcollections are cheap, so being able to load and cache the field all at once is a huge performance gain.
For sure there are other ways to handle this, but I think regardless of your backend database this will be the most efficient for 95% of the scenarios that match the description.
Reply
#6

Oh, don't get me wrong. I totally agree on the final result (reusable component + performance gain). I was just surprised by the amount of code for something that in my opinion is relatively simple. But maybe if I was to develop something similar I would end up with the same amount of code.
CodeIgniter 4 tutorials (EN/FR) - https://includebeer.com
/*** NO support in private message - Use the forum! ***/
Reply




Theme © iAndrew 2016 - Forum software by © MyBB