May 8, 2015

Laravel 5 Eloquent Models & Tinker Tips

Eloquent is Laravel's implementation of ActiveRecord, seen in other programming languages too, like Ruby. It insulates you from the need to use hard SQL queries in your code. Each new ActiveRecord is basically one line of a database table, containing all the columns as object attributes wrapped in a PHP model class. Creating an Eloquent Model is easy:

php artisan make:model Transaction

This creates a PHP class at app/Transaction.php which can be filled with attributes specific to that object model. Another cool thing, is that Laravel will also create a database migration for it; pretty useful since you are likely going to store this object somewhere. Now that we have a model, we can use Tinker to demonstrate how ActiveRecord queries the database.


Assigning Values


Run php artisan tinker from the command line, and let's play around with objects to manipulate our database. Values can be assigned to attributes like so:

$transaction = new App\Transaction
$transaction->debit = '3.33';
$transaction->description = 'cup of coffee';
$transaction->date = Carbon\Carbon::now();
// object is getting filled up, but not yet persisted to the database:
$transaction->save();

This is roughly equal to the MySQL command:
INSERT INTO transactions (debit, description, date) 
   VALUES ('3.33','cup of coffee', NOW());


Looking Up Values


Now that the object has been persisted back to the database, we can verify the added record by looking directly in the database, by doing something like this in MySQL:
GET * FROM transactions;

More elegantly, we can do one of several ActiveRecord queries via Tinker like so:

App\Transaction::all()->toArray();

// or find via database ID key:
$transaction = App\Transaction::find(1);

// or find by column; this returns a Laravel Collection:
$transaction = App\Transaction::where('debit', '3.33')->get();

// or return only the first result as a class object instead:
$transaction = App\Transaction::where('debit', '3.33')->first();


Mass-Assigning Values


Assigning individual values can be tedious and time-consuming. We can mass-assign values to a database row by passing an array like:

App\Transaction::create([
   'debit' => '3.33',
   'description' => 'cup of coffee'
   'date' => Carbon\Carbon::now()
]);

The ability to mass-assign values like this, requires a safeguard to protect us against exploiters using fake fields to inject data via a form. We can build a safeguard by explicitly adding an accepted array of values that are permitted to be filled via mass-assignment. The app/Transaction.php model could look something like this:

class Transaction extends Model {
   protected $fillable = [
      'debit',
      'description',
      'date',
      'credit',
      'total',
      'account'
   ];
}

Mass Assignment will now work for any combination of fillable fields.


Mass-Updating Values


The mass-assign ::create() method above is directly enacted upon an Eloquent class. To update a database record, first create an Eloquent object, then use the ->update() method on it, passing an array of values:

App\Transaction::create(['description'=>'cheap coffee', 'debit'=>'3.33']);
$tn = App\Transaction::where('description', 'cheap coffee')->first();
$tn->update(["debit" => "2.22"]);

The ->update() method will automatically save to the database!

1 comment :