[{"data":1,"prerenderedAt":660},["ShallowReactive",2],{"articles":3},[4,85],{"id":5,"title":6,"author":7,"body":8,"date":73,"description":74,"extension":75,"image":76,"meta":77,"navigation":78,"path":79,"publishedAt":80,"robots":80,"seo":81,"sitemap":82,"stem":83,"updatedAt":80,"__hash__":84},"articles\u002Farticles\u002F1.hello-world.md","Hey there! Welcome to my blog","Amir Swaleh",{"type":9,"value":10,"toc":67},"minimark",[11,16,20,23,28,31,35,38],[12,13,15],"h1",{"id":14},"hey-there-welcome-to-my-blog","Hey There! Welcome to My Blog",[17,18,19],"p",{},"Hi, I’m Amir Swaleh, a web developer living in Amsterdam, The Netherlands. After spending years building websites and apps for other people, I’ve finally decided to make one for myself. This blog is where I’ll share my thoughts, ideas, and maybe even a few prayers.",[17,21,22],{},"As someone who’s spent countless hours writing code, tweaking designs, and making sure everything runs smoothly, it feels awesome to finally create something just for me. Sure, the tech side is fun, but this blog is more about why I love doing what I do: connecting with people, being creative, and always staying curious.",[24,25,27],"h2",{"id":26},"why-now","Why Now?",[17,29,30],{},"You might be thinking, \"Why start a blog now?\" Honestly, I’ve always been so busy with client work that I kept putting it off. But lately, I’ve felt the itch to share more—not just about work, but about life, the journey, and everything in between.",[24,32,34],{"id":33},"whats-coming-up","What’s Coming Up",[17,36,37],{},"Here’s what I’ve got planned:",[39,40,41,49,55,61],"ul",{},[42,43,44,48],"li",{},[45,46,47],"strong",{},"Web Dev Tips:"," Stuff I’ve learned as a full-stack dev, especially with tools like Laravel, Tailwind, and Livewire.",[42,50,51,54],{},[45,52,53],{},"Life as a Coder:"," Real talk about juggling creativity and productivity, and staying sane in a fast-moving industry.",[42,56,57,60],{},[45,58,59],{},"Community Stuff:"," Cool experiences from meetups, conferences, or just collaborating with other developers.",[42,62,63,66],{},[45,64,65],{},"Random Thoughts:"," Sometimes I’ll just write about whatever’s on my mind—big ideas, small wins, or even random fun stuff.",{"title":68,"searchDepth":69,"depth":69,"links":70},"",2,[71,72],{"id":26,"depth":69,"text":27},{"id":33,"depth":69,"text":34},"2025-01-01","Just a small introduction on who I am","md","\u002Fcontent\u002Fsocial-card.svg",{},true,"\u002Farticles\u002Fhello-world",null,{"title":6,"description":74},{"loc":79},"articles\u002F1.hello-world","9hqtHuhDhh7CNubW6WWQTwBhxleZVCCh_Lr1IIsFtsw",{"id":86,"title":87,"author":7,"body":88,"date":73,"description":653,"extension":75,"image":76,"meta":654,"navigation":78,"path":655,"publishedAt":80,"robots":80,"seo":656,"sitemap":657,"stem":658,"updatedAt":80,"__hash__":659},"articles\u002Farticles\u002F2.using-actions-in-laravel.md","How to Use Laravel Actions for Clean Architecture",{"type":9,"value":89,"toc":645},[90,94,101,104,108,111,118,344,353,357,360,366,417,427,431,438,445,532,549,553,559,562,568,571,577,580,586,589,595,598,602,605,625,629,632,638,641],[12,91,93],{"id":92},"using-actions-in-laravel-a-clean-approach-to-business-logic","Using Actions in Laravel: A Clean Approach to Business Logic",[17,95,96,97,100],{},"When building Laravel applications, one of the challenges developers often face is organizing business logic in a way that’s clean, reusable, and easy to maintain. Controllers can quickly become bloated, and models can end up doing more than they should. This is where ",[45,98,99],{},"actions"," come into play. Actions are single-purpose classes that encapsulate a specific piece of business logic, making your code more modular and easier to test.",[17,102,103],{},"In this post, I’ll walk you through an example of how to use actions in Laravel, explain the benefits of this approach.",[24,105,107],{"id":106},"what-are-actions","What Are Actions?",[17,109,110],{},"Actions are essentially classes that handle a single responsibility. For example, instead of writing the logic to update a model directly in a controller or a service class, you can encapsulate that logic in an action class. This keeps your controllers thin and your codebase organized.",[17,112,113,114,117],{},"Here’s an example of an action class called ",[45,115,116],{},"UpdateModel",":",[119,120,126],"pre",{"className":121,"code":122,"filename":123,"language":124,"meta":125,"style":68},"language-php shiki shiki-themes material-theme-lighter github-light nord","class UpdateModel\n{\n    public function execute(Model $model, array $attributes): Model\n    {\n        return DB::transaction(function () use ($model, $attributes) {\n            $model->updateOrFail(\n                Arr::only($attributes, $model->getFillable())\n            );\n\n            return $model;\n        });\n    }\n}\n","UpdateModel.php","php","meta-info=val",[127,128,129,142,148,197,203,249,266,297,306,312,324,332,338],"code",{"__ignoreMap":68},[130,131,134,138],"span",{"class":132,"line":133},"line",1,[130,135,137],{"class":136},"sqL0a","class",[130,139,141],{"class":140},"sIUPB"," UpdateModel\n",[130,143,144],{"class":132,"line":69},[130,145,147],{"class":146},"sIh2P","{\n",[130,149,151,154,157,161,164,168,172,176,179,183,185,188,191,194],{"class":132,"line":150},3,[130,152,153],{"class":136},"    public",[130,155,156],{"class":136}," function",[130,158,160],{"class":159},"sB-4G"," execute",[130,162,163],{"class":146},"(",[130,165,167],{"class":166},"sisaN","Model",[130,169,171],{"class":170},"ssiHu"," $",[130,173,175],{"class":174},"sd9w7","model",[130,177,178],{"class":146},",",[130,180,182],{"class":181},"stzsX"," array",[130,184,171],{"class":170},[130,186,187],{"class":174},"attributes",[130,189,190],{"class":146},")",[130,192,117],{"class":193},"sW0zq",[130,195,196],{"class":166}," Model\n",[130,198,200],{"class":132,"line":199},4,[130,201,202],{"class":146},"    {\n",[130,204,206,210,213,216,219,221,224,227,230,233,236,238,240,242,244,246],{"class":132,"line":205},5,[130,207,209],{"class":208},"sWXoK","        return",[130,211,212],{"class":166}," DB",[130,214,215],{"class":193},"::",[130,217,218],{"class":159},"transaction",[130,220,163],{"class":146},[130,222,223],{"class":136},"function",[130,225,226],{"class":146}," ()",[130,228,229],{"class":181}," use",[130,231,232],{"class":146}," (",[130,234,235],{"class":170},"$",[130,237,175],{"class":174},[130,239,178],{"class":146},[130,241,171],{"class":170},[130,243,187],{"class":174},[130,245,190],{"class":146},[130,247,248],{"class":146}," {\n",[130,250,252,255,257,260,263],{"class":132,"line":251},6,[130,253,254],{"class":170},"            $",[130,256,175],{"class":174},[130,258,259],{"class":193},"->",[130,261,262],{"class":159},"updateOrFail",[130,264,265],{"class":146},"(\n",[130,267,269,272,274,277,279,281,283,285,287,289,291,294],{"class":132,"line":268},7,[130,270,271],{"class":166},"                Arr",[130,273,215],{"class":193},[130,275,276],{"class":159},"only",[130,278,163],{"class":146},[130,280,235],{"class":170},[130,282,187],{"class":174},[130,284,178],{"class":146},[130,286,171],{"class":170},[130,288,175],{"class":174},[130,290,259],{"class":193},[130,292,293],{"class":159},"getFillable",[130,295,296],{"class":146},"())\n",[130,298,300,303],{"class":132,"line":299},8,[130,301,302],{"class":146},"            )",[130,304,305],{"class":170},";\n",[130,307,309],{"class":132,"line":308},9,[130,310,311],{"emptyLinePlaceholder":78},"\n",[130,313,315,318,320,322],{"class":132,"line":314},10,[130,316,317],{"class":208},"            return",[130,319,171],{"class":170},[130,321,175],{"class":174},[130,323,305],{"class":170},[130,325,327,330],{"class":132,"line":326},11,[130,328,329],{"class":146},"        })",[130,331,305],{"class":170},[130,333,335],{"class":132,"line":334},12,[130,336,337],{"class":146},"    }\n",[130,339,341],{"class":132,"line":340},13,[130,342,343],{"class":146},"}\n",[17,345,346,347,349,350,352],{},"In this example, the ",[45,348,116],{}," action is responsible for updating a given model with the provided attributes. It uses a database transaction to ensure data integrity and leverages ",[45,351,262],{}," to throw an exception if the update fails.",[24,354,356],{"id":355},"how-to-use-actions-in-your-application","How to Use Actions in Your Application",[17,358,359],{},"Using actions in your application is straightforward. Let’s say you have a controller method that handles updating a user’s profile. Instead of writing the update logic directly in the controller, you can delegate that responsibility to the UpdateModel action.",[17,361,362,363,365],{},"Here’s how you might use the ",[45,364,116],{}," action in a controller:",[119,367,370],{"className":121,"code":368,"filename":369,"language":124,"meta":125,"style":68},"$updatedUser = app(UpdateModel::class)->execute($user, $attributes);\n","UpdateUserController.php",[127,371,372],{"__ignoreMap":68},[130,373,374,376,379,382,385,387,389,391,393,395,397,400,402,404,407,409,411,413,415],{"class":132,"line":133},[130,375,235],{"class":170},[130,377,378],{"class":174},"updatedUser",[130,380,381],{"class":193}," =",[130,383,384],{"class":159}," app",[130,386,163],{"class":146},[130,388,116],{"class":166},[130,390,215],{"class":193},[130,392,137],{"class":181},[130,394,190],{"class":146},[130,396,259],{"class":193},[130,398,399],{"class":159},"execute",[130,401,163],{"class":146},[130,403,235],{"class":170},[130,405,406],{"class":174},"user",[130,408,178],{"class":146},[130,410,171],{"class":170},[130,412,187],{"class":174},[130,414,190],{"class":146},[130,416,305],{"class":170},[17,418,419,420,423,424,426],{},"In this example, the controller you are using is only responsible for handling the HTTP request and response. The actual business logic, like ",[45,421,422],{},"updating the user",", is delegated to the ",[45,425,116],{}," action. This separation of concerns makes your code easier to read, test, and maintain.",[24,428,430],{"id":429},"what-does-getfillable-do","What Does getFillable() Do?",[17,432,433,434,437],{},"In Laravel, the ",[45,435,436],{},"getFillable()"," method is a built-in method on Eloquent models that returns an array of attributes that are mass-assignable. Mass assignment is a convenient way to update multiple attributes of a model at once, but it can also pose a security risk if not handled properly.",[17,439,440,441,444],{},"By defining a ",[45,442,443],{},"$fillable"," property on your model, you specify which attributes can be mass-assigned. For example:",[119,446,449],{"className":121,"code":447,"filename":448,"language":124,"meta":125,"style":68},"class User extends Model\n{\n    protected $fillable = [\n        'name',\n        'email',\n        'password',\n    ];\n}\n\n","User.php",[127,450,451,464,468,483,499,510,521,528],{"__ignoreMap":68},[130,452,453,455,458,461],{"class":132,"line":133},[130,454,137],{"class":136},[130,456,457],{"class":140}," User",[130,459,460],{"class":136}," extends",[130,462,196],{"class":463},"sqeik",[130,465,466],{"class":132,"line":69},[130,467,147],{"class":146},[130,469,470,473,475,478,480],{"class":132,"line":150},[130,471,472],{"class":136},"    protected",[130,474,171],{"class":170},[130,476,477],{"class":174},"fillable",[130,479,381],{"class":193},[130,481,482],{"class":146}," [\n",[130,484,485,489,493,496],{"class":132,"line":199},[130,486,488],{"class":487},"sqDQg","        '",[130,490,492],{"class":491},"sE4Qb","name",[130,494,495],{"class":487},"'",[130,497,498],{"class":146},",\n",[130,500,501,503,506,508],{"class":132,"line":205},[130,502,488],{"class":487},[130,504,505],{"class":491},"email",[130,507,495],{"class":487},[130,509,498],{"class":146},[130,511,512,514,517,519],{"class":132,"line":251},[130,513,488],{"class":487},[130,515,516],{"class":491},"password",[130,518,495],{"class":487},[130,520,498],{"class":146},[130,522,523,526],{"class":132,"line":268},[130,524,525],{"class":146},"    ]",[130,527,305],{"class":170},[130,529,530],{"class":132,"line":299},[130,531,343],{"class":146},[17,533,534,535,537,538,541,542,545,546,548],{},"In the ",[45,536,116],{}," action, ",[45,539,540],{},"Arr::only($attributes, $model->getFillable())"," ensures that only the fillable attributes from the ",[45,543,544],{},"$attributes"," array are passed to the ",[45,547,262],{}," method. This prevents potential security issues by ensuring that only safe, whitelisted attributes are updated.",[24,550,552],{"id":551},"benefits-of-using-actions","Benefits of Using Actions",[17,554,555,556],{},"1. ",[45,557,558],{},"Single Responsibility Principle (SRP)",[17,560,561],{},"Actions adhere to the Single Responsibility Principle by design. Each action handles one specific task, which makes your codebase more modular and easier to understand. For example, the UpdateModel action is only responsible for updating a model.",[17,563,564,565],{},"2. ",[45,566,567],{},"Reusability",[17,569,570],{},"Actions can be reused across your application. For instance, if you need to update a model in multiple places (e.g., in a controller and a queue job), you can simply call the same action instead of duplicating code.",[17,572,573,574],{},"3. ",[45,575,576],{},"Testability",[17,578,579],{},"Because actions are isolated and self-contained, they’re easy to test. You can write unit tests for your actions without worrying about the complexities of the rest of your application. For example, testing the UpdateModel action would involve mocking the model and verifying that it updates correctly.",[17,581,582,583],{},"4. ",[45,584,585],{},"Improved Readability",[17,587,588],{},"By moving business logic out of controllers and into actions, your controllers become much cleaner and easier to read. This makes it easier for other developers (or your future self) to understand what’s happening in the code.",[17,590,591,592],{},"5. ",[45,593,594],{},"Transaction Handling",[17,596,597],{},"Actions make it easy to encapsulate database transactions. In the UpdateModel example, the entire update operation is wrapped in a transaction, ensuring data consistency. If you need to add more steps to the transaction later, you can do so without modifying the controller.",[24,599,601],{"id":600},"when-to-use-actions","When to Use Actions",[17,603,604],{},"Actions are particularly useful for:",[39,606,607,613,619],{},[42,608,609,612],{},[45,610,611],{},"Complex Business Logic",": If a task involves multiple steps or requires interaction with several models, an action can help keep things organized.",[42,614,615,618],{},[45,616,617],{},"Repeated Logic",": If you find yourself writing the same code in multiple places, it’s a good candidate for an action.",[42,620,621,624],{},[45,622,623],{},"Testing",": If you want to make your code more testable, actions are a great way to isolate logic.",[24,626,628],{"id":627},"final-thoughts","Final Thoughts",[17,630,631],{},"Using actions in Laravel is a powerful way to keep your codebase clean, maintainable, and testable. By encapsulating business logic in single-purpose classes, you can follow the Single Responsibility Principle, improve reusability, and make your controllers more focused on their primary role.",[17,633,634,635,637],{},"The ",[45,636,116],{}," action we discussed is just one example of how you can use actions in your application. As your application grows, you’ll likely find more opportunities to extract logic into actions, making your codebase more modular and easier to work with.",[17,639,640],{},"So, the next time you’re tempted to write business logic directly in a controller, consider creating an action instead. Your future self (and your team) will thank you!",[642,643,644],"style",{},"html pre.shiki code .sqL0a, html code.shiki .sqL0a{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#81A1C1}html pre.shiki code .sIUPB, html code.shiki .sIUPB{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#8FBCBB}html pre.shiki code .sIh2P, html code.shiki .sIh2P{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#ECEFF4}html pre.shiki code .sB-4G, html code.shiki .sB-4G{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#88C0D0}html pre.shiki code .sisaN, html code.shiki .sisaN{--shiki-light:#E2931D;--shiki-default:#005CC5;--shiki-dark:#8FBCBB}html pre.shiki code .ssiHu, html code.shiki .ssiHu{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#81A1C1}html pre.shiki code .sd9w7, html code.shiki .sd9w7{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#D8DEE9}html pre.shiki code .stzsX, html code.shiki .stzsX{--shiki-light:#F76D47;--shiki-default:#D73A49;--shiki-dark:#81A1C1}html pre.shiki code .sW0zq, html code.shiki .sW0zq{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#81A1C1}html pre.shiki code .sWXoK, html code.shiki .sWXoK{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#81A1C1;--shiki-dark-font-style:inherit}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sqeik, html code.shiki .sqeik{--shiki-light:#E2931D;--shiki-light-font-weight:inherit;--shiki-default:#6F42C1;--shiki-default-font-weight:inherit;--shiki-dark:#8FBCBB;--shiki-dark-font-weight:bold}html pre.shiki code .sqDQg, html code.shiki .sqDQg{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#ECEFF4}html pre.shiki code .sE4Qb, html code.shiki .sE4Qb{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#A3BE8C}",{"title":68,"searchDepth":69,"depth":69,"links":646},[647,648,649,650,651,652],{"id":106,"depth":69,"text":107},{"id":355,"depth":69,"text":356},{"id":429,"depth":69,"text":430},{"id":551,"depth":69,"text":552},{"id":600,"depth":69,"text":601},{"id":627,"depth":69,"text":628},"Learn how to use Laravel actions to structure and manage business logic cleanly, improving code maintainability, scalability, and separation of concerns",{},"\u002Farticles\u002Fusing-actions-in-laravel",{"title":87,"description":653},{"loc":655},"articles\u002F2.using-actions-in-laravel","8aYXwsVuCSbn_YonA4nAsf2l69vNcn_7NkInJnEt5LU",1776111412329]