# With Attributes (`WithAttributes` trait) ## Scope Use this reference when an action stores and validates input via internal attributes instead of method arguments. ## Recap - Documents attribute lifecycle APIs (`setRawAttributes`, `fill`, `fillFromRequest`, readers/writers). - Clarifies behavior of key collisions (`fillFromRequest`: request data wins over route params). - Lists validation/authorization hooks reused from controller validation pipeline. - Includes end-to-end example from fill to `validateAttributes()` and `handle(...)`. ## Methods provided (`WithAttributes` trait) ### `setRawAttributes` Replaces all attributes with the provided payload. ```php $action->setRawAttributes([ 'key' => 'value', ]); ``` ### `fill` Merges provided attributes into existing attributes. ```php $action->fill([ 'key' => 'value', ]); ``` ### `fillFromRequest` Merges request input and route parameters into attributes. Request input has priority over route parameters when keys collide. ```php $action->fillFromRequest($request); ``` ### `all` Returns all attributes. ```php $action->all(); ``` ### `only` Returns attributes matching the provided keys. ```php $action->only('title', 'body'); ``` ### `except` Returns attributes excluding the provided keys. ```php $action->except('body'); ``` ### `has` Returns whether an attribute exists for the given key. ```php $action->has('title'); ``` ### `get` Returns the attribute value by key, with optional default. ```php $action->get('title'); $action->get('title', 'Untitled'); ``` ### `set` Sets an attribute value by key. ```php $action->set('title', 'My blog post'); ``` ### `__get` Accesses attributes as object properties. ```php $action->title; ``` ### `__set` Updates attributes as object properties. ```php $action->title = 'My blog post'; ``` ### `__isset` Checks attribute existence as object properties. ```php isset($action->title); ``` ### `validateAttributes` Runs authorization and validation using action attributes and returns validated data. ```php $validatedData = $action->validateAttributes(); ``` ## Methods used (`AttributeValidator`) `WithAttributes` uses the same authorization/validation hooks as `AsController`: - `prepareForValidation` - `authorize` - `rules` - `withValidator` - `afterValidator` - `getValidator` - `getValidationData` - `getValidationMessages` - `getValidationAttributes` - `getValidationRedirect` - `getValidationErrorBag` - `getValidationFailure` - `getAuthorizationFailure` ## Example ```php class CreateArticle { use AsAction; use WithAttributes; public function rules(): array { return [ 'title' => ['required', 'string', 'min:8'], 'body' => ['required', 'string'], ]; } public function handle(array $attributes): Article { return Article::create($attributes); } } $action = CreateArticle::make()->fill([ 'title' => 'My first post', 'body' => 'Hello world', ]); $validated = $action->validateAttributes(); $article = $action->handle($validated); ``` ## Checklist - Attribute keys are explicit and stable. - Validation rules match expected attribute shape. - `validateAttributes()` is called before side effects when needed. - Validation/authorization hooks are tested in focused unit tests. ## Common pitfalls - Mixing attribute-based and argument-based flows inconsistently in the same action. - Assuming route params override request input in `fillFromRequest` (they do not). - Skipping `validateAttributes()` when using external input. ## References - https://www.laravelactions.com/2.x/with-attributes.html