In my years of developing systems and API's for various business verticals, one of the most prominent problem I have encountered and still encountering until now are attributes that were not properly cast to their expected data type. It is always such a headache when you know you should be working with a `boolean` value but receiving a `string` instead. Or an `integer` or `float` value that is not properly mutated and left as `string`, especially when working on financial-related stuff. Or worse, an `array` of objects that is, guess what, left as `string`. In Laravel, attribute casting has vastly improved since version 7.x. We only used to have [Mutators and Accessors](https://laravel.com/docs/6.x/eloquent-mutators#array-and-json-casting) available to us but now, [class-based Custom Casts](https://laravel.com/docs/10.x/eloquent-mutators#custom-casts/) is available. And it is also rich with other sub-features such as [Value Object Casting](https://laravel.com/docs/10.x/eloquent-mutators#value-object-casting) and [Serialization](https://laravel.com/docs/10.x/eloquent-mutators#array-json-serialization). Just another reason to already bunch of reasons why I love working with Eloquent ORM. Casting is our first layer of assurance that we are getting correct data types post database query. And these framework-native features give us more than enough reason to always casts our attributes. So please, don't be lazy and utilize it, for your own sanity. **TIP:** If you don't use Eloquent when querying data from your database but still want your attributes to be cast properly? Just manually instantiate your rows instead: ``` use App\Models\Posts; $posts = \DB::table('posts')->get(); $posts = $posts->map(fn ($post) => new Post($post)); ```
Published Articles
Eloquent ORM is probably the most appreciated features of Laravel. It enables programmers to interact with the database in a fluent manner. And just like any other features in Laravel, it has couple hidden gems that you probably never knew existed. In this article, let's take a look at some of these hidden gems that I personally use quite so often. # whereKey / whereKeyNot That's right! These are Eloquent methods are specific for querying a model by its primary key. The obvious benefit of this is that you, as the programmer, don't need to remember the name of the model's primary key. ``` // Instead of doing... Post::whereIn('id', [1,2,3])->get(); Post::whereNotIn('id', [1,2,3])->get(); // You can do... Post::whereKey([1,2,3])->get(); Post::whereKeyNot([1,2,3])->get(); ``` # qualifyColumn You can use this method if you want to prepend your columns with the table name. Really helpful for long queries with nested conditions. ``` $sql = Post::where(function ($query) { $query->whereNotNull($query->qualifyColumn('published_at')); })->toSql(); dd($sql); // select * from `posts` where (`posts`.`published_at` is not null) and `posts`.`deleted_at` is null ``` # getQualifiedKeyName This method simply returns the name of the primary key of the model with the table name. ``` (new \App\Models\Post)->getQualifiedKeyName(); // Will return 'posts.id' (new \App\Models\Post)->getKeyName(); // Will return 'id' ``` # increment / decrement Often times we have a column on a model that we need to manually increment/decrement. So instead of using the "update" method, we can use "increment / decrement" instead. Also, increment and decrement methods both accepts 2nd parameter as the amount of increment, and 3rd parameter as an array of extra columns you wish to update. # when / unless If you ever come across a situation wherein your queries are based on a condition then these methods might be perfect for your use-case. You can use `when` if you want to apply a callback to an Eloquent query when a certain condition is true. ``` Post::when($someBoolean, function () { // This call back will run if $someBoolean is true... }); ``` You can use `unless` if you want to apply a callback to an Eloquent query when a certain condition is false. ``` Post::unless($someBoolean, function () { // This call back will run if $someBoolean is false... }); ``` You can also pass a third parameter to both methods as a default callback. And both methods are also chainable to other Eloquent methods! # loadMissing This method is almost the same as the `load` method. But as the name implies, it will only load relationship that has not yet been loaded on the current model. This means performance savings when lazy loading relationships. # The magic where When doing where conditions on your queries, you can just append the name of the column to the where method in camel-case format, like so: ``` $sql = User::whereEmail('john@doe.com')->toSql(); dd($sql); // select * from `users` where `email` = ? ``` Hopefully, you learned something from this article and you'll be able to utilize these methods. Don't forget to visit the official Laravel documentation for more info: [https://laravel.com/docs/7.x/eloquent](https://laravel.com/docs/7.x/eloquent) Cheers!