stechstudio / laravel-record by jszobody

What if Laravel's Collection and Model classes had a baby?
10,602
22
4
Package Data
Maintainer Username: jszobody
Maintainer Contact: joseph@stechstudio.com (Joseph Szobody)
Package Create Date: 2017-06-12
Package Last Update: 2024-03-12
Home Page:
Language: PHP
License: MIT
Last Refreshed: 2024-12-22 03:03:33
Package Statistics
Total Downloads: 10,602
Monthly Downloads: 246
Daily Downloads: 0
Total Stars: 22
Total Watchers: 4
Total Forks: 1
Total Open Issues: 0

Laravel Record

Software License Quality Score Total Downloads

I'm going to assume you already know all about Laravel's awesome Collection class, and hopefully you've read Refactoring to Collections. (If you haven't, stop what you're doing and go buy that PDF. You'll thank me later.)

I also assume you know all about Eloquent models.

But have you ever wanted some of the functionality of a model, merged onto a collection?

This is a super small, single-class library that brings those together just a bit.

Benefits

Starting with the Collection class, I wanted to add:

  1. Magic getter for attributes. If you have key/value pairs in your collection, the Collection class does provide the get method. But I'm lazy. And I like accessing my collection with plain 'ol object notation. You know, like a model. Record lets you do $collection->attribute.

  2. New collection for sub-arrays. If you hand a multi-dimensional array to collect() and access a nested array, it's still just an array. Like $collection->get('attribute')['subattribute']. I want collections all the way down! This will turn any sub-array into a new instance of Record, allowing you to do $record->attribute->subattribute->as->deep->as->your->array->goes. And because you still have a real collection at each level, you can use all of the goodies like $record->attribute->subattribute->count().

  3. Custom accessors. Just like Eloquent, you can extend the Record class and define a custom accessor. Create a getFooAttribute() method and then just use $collection->foo to get your custom computed attribute.

Quick example: handling rich arrays

I find myself frequently needing to handle a multi-dimensional array, often a response from a remote web service. This array may have attributes (like 'name' or 'id') as well as a nested collections (like 'data' or 'rows').

Consider this:

{
  "name" : "My Blog",
  "url" : "http://foo.dev",
  "posts" : [
    {
      "id" : 1,
      "title" : "Hello World",
      "content" : "...",
      "comments" : [
        {
          "name" : "John Doe",
          "email" : "john@example.com",
          "content": "..."
        }
      ]
    },
    {
      "id" : 2,
      "title" : "My second post",
      "content" : "...",
      "comments" : [
        ...
      ]
    }
  ]
}

We can take this whole payload and navigate it quite nicely with Record:

$record = record(json_decode($webServiceResponse, true));

echo $record->name; // My Blog
echo $record->posts->count(); // 2
echo $record->posts->first()->title; // Hello World
echo $record->posts->first()->comments->count(); // 1

Nice! At each level I get a combination Laravel's Collection class, plus some attribute goodness borrowed from Model.

Furthermore I might extend Record and create a class with custom accessors to sanitize content, or split the name into first and last, or... you get the idea.

Installation

You know the drill.

composer require sts/laravel-record

Then you can either:

$record = new STS\Record\Record([...]);

Or you can use the record helper method:

$record = record([...]);