Laravel's Fluent class delivers enhanced data transformation capabilities for action classes. Converting from arrays to Fluent instances when passing attributes to actions brings numerous advantages to your codebase.
Arrays provide a basic approach for transferring data to actions, but Fluent instances offer integrated transformation methods and more elegant validation options. This becomes particularly valuable when handling sophisticated data transformations or implementing conditional validation logic.
Here's a basic implementation:
namespace App\Actions; use App\Models\Product;use Illuminate\Support\Fluent; class CreateProduct{ // Using Fluent instead of array public function execute(Fluent $data): Product { return Product::create([ 'name' => $data->name, 'description' => $data->description, 'categories' => $data->array('categories'), 'status' => $data->enum('status', ProductStatus::class), 'published_at' => $data->date('published_at') ]); }} // Usage in testsit('can create a new product', function() { $product = (new CreateProduct)->execute(new Fluent([ 'name' => 'Premium Headphones', 'description' => 'Noise-cancelling wireless headphones', 'categories' => ['electronics', 'audio'], 'status' => ProductStatus::Active, 'published_at' => now() ]));});
The Fluent approach shines when implementing complex validation with conditional rules:
class PaymentValidator{ public function validate(array $data) { $validator = Validator::make($data, [ 'method' => 'required|string', 'amount' => 'required|numeric|min:1' ]); $validator->sometimes( ['account_name', 'routing_number'], 'required', function (Fluent $input) { return $input->method === 'bank_transfer'; } ); $validator->sometimes( 'card_verification', 'required|size:3', function (Fluent $input) { return $input->get('method') === 'credit_card' && $input->get('amount') > 500; } ); return $validator; }}
Using Fluent instances provides a more sophisticated approach to data handling in your actions and validations. It functions as a versatile toolkit for transformations while maintaining code clarity and readability. The built-in accessors and transformation methods significantly reduce boilerplate code while making your intentions explicit.