Skip to content
Diego Vieira edited this page Mar 21, 2017 · 3 revisions

Metable

It requires additional table in your db. You can find the migration under Sofa\Eloquence\Metable - for the time being, create you own migration and simply copy the code without namespace. Soon there will be a console command and publishing option for the migration.

Use it to add meta-attributes to your model, if it has arbitrary number of attributes. For example Hotel or Product:

<?php 

namespace App;

use Sofa\Eloquence\Eloquence; // base trait
use Sofa\Eloquence\Metable; // extension trait

class Hotel extends \Eloquent {

    use Eloquence, Metable;
}

It's just like working with normal attributes - see it in action:

Start tinker and run each of the commands below

php artisan tinker
// Assign attributes as usually..
>>> $beachHotel = new App\Hotel
>>> $beachHotel->name = 'Sea View'
>>> $beachHotel->beach_type = 'sandy'
>>> $beachHotel->beach_distance = 50
>>> $beachHotel->aquapark = true

// ..then simply save the model
>>> $beachHotel->save()

// Now let's check it:
>>> $beachHotel = App\Hotel::latest()->first()
=> <App\Hotel #0000000057b8af2b000000000f50d29e> {
       id: 106,
       name: "Sea View",
       deleted_at: null,
       created_at: "2015-04-30 14:30:51",
       updated_at: "2015-04-30 14:30:51"
   }

// meta attributes are appended to the array representation
>>> $beachHotel->toArray()
=> [
       "id"             => 106,
       "name"           => "Sea View",
       "deleted_at"     => null,
       "created_at"     => "2015-04-30 14:30:51",
       "updated_at"     => "2015-04-30 14:30:51",
       "beach_distance" => "50",
       "beach_type"     => "sandy",
       "aquapark"       => "1"
   ]


>>> $skiHotel = new App\Hotel
>>> $skiHotel->name = 'Alexander'
>>> $skiHotel->lifts_distance = 300
>>> $skiHotel->sauna = true
>>> $skiHotel->gym = true
>>> $skiHotel->activities = ['trekking', 'cross-country', 'husky-village']
>>> $skiHotel->garage = 'yes, 10EUR/day'
>>> $skiHotel->save()
>>> $skiHotel = App\Hotel::latest()->first()
=> <App\Hotel #0000000057b8af54000000000f50d29e> {
       id: 107,
       name: "Alexander",
       deleted_at: null,
       created_at: "2015-04-30 14:39:20",
       updated_at: "2015-04-30 14:39:20"
   }
>>> $skiHotel->toArray()
=> [
      "id"             => 107,
      "name"           => "Alexander",
      "deleted_at"     => null,
      "created_at"     => "2015-04-30 14:39:20",
      "updated_at"     => "2015-04-30 14:39:20",
      "lifts_distance" => "300",
      "sauna"          => "1",
      "gym"            => "1",
      "activities"     => "[\"trekking\",\"cross-country\",\"husky-village\"]",
      "garage"         => "yes, 10EUR/day"
   ]


// You can fill meta attributes as well (fillable/guarded properties still apply)
>>> $shirt = new App\Product(['name' => 'Hipster T-shirt', 'price' => 125, 'color'=> 'green-white'])
// name and color are fillable, but price is not, so it doesn't get filled:
=> <App\Product #000000006a37bcb20000000031dd9b05> {
       name: "Hipster T-shirt",
       metaAttributes: <Sofa\Eloquence\Metable\AttributeBag #000000006a37bc890000000031dd9b05> [
           "color" => <Sofa\Eloquence\Metable\Attribute #000000006a37bc8d0000000031dd9b05> {
               meta_key: "color",
               meta_type: "string",
               meta_value: "green-white"
           }
       ]
   }


// Values are stored as strings and automatically cast/mutated for you:
>>> $shirt->available_from = Carbon::today()->addMonth();
>>> $shirt->price = 125.5
>>> $shirt->save()

>>> $shirt = App\Product::latest()->first()
>>> $shirt->price
=> 125.5 // float
>>> $shirt->available_from
=> <Carbon\Carbon #000000006a37bcb50000000031dd8a65> {
       date: "2015-05-30 00:00:00.000000",
       timezone_type: 3,
       timezone: "Europe/Warsaw"
   }



// You can also query meta attributes:
$hotels = App\Hotel::orderBy('beach_distance', 'asc')->take(10)->get();
$closestToTheBeach = App\Hotel::min('beach_distance');
$hotelsWithSauna = App\Hotel::whereNotNull('sauna')->get();
Clone this wiki locally