This Banner is For Sale !!
Get your ad here for a week in 20$ only and get upto 15k traffic Daily!!!

Laravel update actions simplified – DEV Community


When constructing API’s, we regularly come throughout CRUD operations, though these operations are one of many first issues we be taught once we begin working with backend, a few of these operations might have considerably much less code.

Apart from that, this code ceaselessly will get duplicated throughout controllers. By means of my journey working with Laravel, I’ve seen that this occurs usually in replace capabilities, and that is why I made a decision to summary this implementation.

I’ve determined to summary this course of with a design that makes the abstraction seems to be like a lot of Laravel’s Eloquent helper capabilities, giving a sense that the abstraction is native, such because the findOrFail() operate.



Content material



Standard method

Earlier than we soar into the abstraction, let’s check out how an replace operation seems to be like when conventionally carried out.

<?php

namespace AppHttpControllers;

use AppModelsUser;
use IlluminateHttpRequest;
use IlluminateHttpResponse;

class UsersController extends Controller
{
    public operate replace(Request $request): Response
    {
        $consumer = Person::discover($request->id);

        if ($consumer === null) {
            return response(
                    "Person with id {$request->id} not discovered",
                    Response::HTTP_NOT_FOUND
                );
        }

        $consumer->fill($request->all());

        if ($consumer->replace() === false) {
            return response(
                    "Could not replace the consumer with id {$request->id}",
                    Response::HTTP_BAD_REQUEST
                );
        }

        return response($consumer);
    }
}
Enter fullscreen mode

Exit fullscreen mode

On the first line, we’re querying a consumer by its ID and storing the end result into the $consumer object.

Then, on the first conditional, we’re checking if the $consumer is null, whether it is, it implies that no report with the given ID was discovered and an error message with standing 404 will likely be responded.

Subsequent, in case the report received discovered, we are going to fill the consumer with the info that we wish to replace.

Thereafter, we’ve a second conditional the place we’re calling $user->replace(), this operate returns true or false to tell us if the info received efficiently up to date. In case it returns false, an error message with standing 400 will likely be responded.

Lastly, if the info received efficiently up to date, we render the up to date consumer as a response.



Shortening it

Since findOrFail() was talked about, why not use this helper operate to shorten our code? When utilizing this method, it will take away at the least 5 traces from the replace motion of our controller, as proven within the code instance down under.

<?php

namespace AppHttpControllers;

use AppModelsUser;
use IlluminateHttpRequest;
use IlluminateHttpResponse;

class UsersController extends Controller
{
    public operate replace(Request $request): Response
    {
        $consumer = Person::findOrFail($request->id);

        $consumer->fill($request->all());

        if ($consumer->replace() === false) {
            return response(
                "Could not replace the consumer with id {$request->id}",
                Response::HTTP_BAD_REQUEST
            );
        }

        return response($consumer);
    }
}
Enter fullscreen mode

Exit fullscreen mode

On the first line, we’re querying a consumer by its ID utilizing the findOrFail() operate. This operate has a particular habits the place an exception will get thrown in case the info of the given ID isn’t discovered.

To take advantage of out of this modification, we have to know methods to automate the dealing with of the exception thrown by the findOrFail(). In any other case, it will be vital to make use of a strive/catch block and the variety of traces can be just about the identical.

Subsequent, in case an exception will get not thrown, we are going to fill the consumer with the info that we wish to replace.

Thereafter, we’ve a second conditional the place we’re calling $user->replace(), this operate returns true or false to tell us if the info received efficiently up to date. In case it returns false, an error message with standing 400 will likely be responded.

Lastly, if the consumer was accurately up to date, we render the up to date consumer as a response.



Abstracting it

Now that we’ve seen two other ways of implementing the replace motion on Laravel, let’s see how we will summary this implementation in a method that we get excessive reusability with easy utilization out of this abstraction.

Since this abstraction interacts with fashions, I needed to keep away from utilizing inheritance as a result of it will be a coupling too excessive for an abstraction so simple as this one.

Moreover, I wish to depart the inheritance within the fashions open for utilization, whether or not by a workforce member resolution or by some particular use case.

For that purpose, I’ve chosen to implement the abstraction in a Trait. In another way from C++ the place we will use a number of inheritance, in PHP a Trait is the mechanism to scale back limitations round single inheritance.

Apart from that, I’ve a private rule the place I exploit Traits solely when an implementation will get extremely reused, since most of my controllers find yourself having an replace motion, in my context, that is one thing extremely reused.



Trait abstraction

<?php

namespace AppHelpers;

use AppExceptionsModelUpdatingException;
use IlluminateDatabaseEloquentModel;

trait UpdateOrFail
{
    /**
     * Discover a mannequin by id, fill the mannequin with an array of attributes, replace
     * the mannequin within the database, in any other case it throws an exception.
     *
     * @param  int  $id
     * @param  array  $attributes
     * @return bool
     *
     * @throws AppExceptionsModelUpdatingException
     * @return IlluminateDatabaseEloquentModel;
     */
    public static operate updateOrFail(int $id, array $attributes): Mannequin
    {
        $mannequin = static::findOrFail($id)->fill($attributes);

        if ($mannequin->replace() === false) {
            throw new ModelUpdatingException($id, get_class($mannequin));
        }

        return $mannequin;
    }
}
Enter fullscreen mode

Exit fullscreen mode

Within the first line of the updateOrFail() operate, we’re utilizing the static:: name to point that we wish to work together with the category utilizing this Trait. Since this class will likely be a mannequin, which means that we’re accessing the properties and capabilities of the mannequin implementing the Trait.

Then we’re calling the findOrFail() operate, passing the ID of the report we wish to retrieve from the database. As soon as the report will get discovered and a populated mannequin will get returned, we’re chaining the fill() operate name passing the info that we wish to replace.

Subsequently, we’ve a conditional the place we’re calling $user->replace(), this operate returns true or false to tell us if the info received efficiently up to date. In case it returns false, a customized exception will get thrown.

Lastly, after a profitable replace, we return the up to date mannequin.



Customized exception

Right here we’re utilizing the identical approach defined within the Laravel customized exceptions submit. For those who didn’t learn the submit but, take a second to learn it, so you can also make sense out of this part.

<?php

namespace AppExceptions;

use IlluminateSupportStr;
use IlluminateHttpResponse;

class ModelUpdatingException extends ApplicationException
{
    public operate __construct(personal int $id, personal string $mannequin)
    {
        $this->mannequin = Str::afterLast($mannequin, '');
    }

    public operate standing(): int
    {
        return Response::HTTP_BAD_REQUEST;
    }

    public operate assist(): string
    {
        return trans('exception.model_not_updated.assist');
    }

    public operate error(): string
    {
        return trans('exception.model_not_updated.error', [
            'id' => $this->id,
            'model' => $this->model,
        ]);
    }
}
Enter fullscreen mode

Exit fullscreen mode

On the class definition, we’re extending the ApplicationException which is an summary class used to implement the implementation of the standing(), assist() and error() capabilities, and assure that Laravel will be capable of deal with this exception routinely.

Following the category definition, we’ve the constructor the place property promotion is getting used to make the code cleaner. As parameters, we’ve $id, which accommodates the ID of the report we wish to question from the database at our Trait, and $mannequin the place the total class title of the mannequin might be discovered.

Contained in the constructor, we’re extracting the mannequin title out of the total class title, the total title can be one thing like AppModelsUser, and we wish simply the Person half. That is getting executed, so we will automate the error message into one thing that is smart to the particular person interacting with our API in case it’s not attainable to seek out the report of a given ID.

Subsequent we’ve the implementation of the standing() operate the place we’re returning the 400 HTTP standing.

Thereafter, we’ve the assist() operate, the place we’re returning a translated string that signifies a attainable answer to the error. In case you’re questioning, the translated string can be evaluated to Examine your replace parameters and check out once more.

Lastly, we’ve the error() operate the place the error that occurred will get specified, as within the earlier operate we’re utilizing a translated string, however in another way from earlier than, right here we’re utilizing the replace parameters function from trans().

This method received chosen to offer us a dynamic error message with context. Right here, the translated string can be evaluated to one thing like Person with id 1 not up to date.

With this construction, if the goal mannequin modifications, the message emitted by the exception would change as effectively because the mannequin title will get dynamically outlined.

As a secondary instance, think about that now, you’re interacting with a Sale mannequin, on this case the message would routinely change to Sale with id 2 not up to date.



Utilizing the abstraction

Now that our abstraction received outlined, and we assured that the error dealing with was in place, we have to use our UpdateOrFail Trait within the fashions that we wish to have this simplified replace habits.

To attain that, we simply should put in our fashions the use UpdateOrFail; precisely like the opposite Traits that usually Laravel brings within the fashions, you possibly can see it with extra particulars within the code instance down under.

<?php

namespace AppModels;

use AppHelpersUpdateOrFail;
use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateFoundationAuthUser as Authenticatable;
use IlluminateNotificationsNotifiable;
use LaravelSanctumHasApiTokens;

class Person extends Authenticatable
{
    use HasFactory;
    use Notifiable;
    use HasApiTokens;
    use UpdateOrFail;

    ...
}
Enter fullscreen mode

Exit fullscreen mode



Last implementation

As a last end result, we find yourself with an API name that appears like Person::updateOrFail($id, $params) leaving us with an replace motion in our controllers that has a single line of implementation, and it’s extremely reusable.

<?php

namespace AppHttpControllers;

use AppModelsUser;
use IlluminateHttpRequest;
use IlluminateHttpResponse;

class Customers extends Controller
{

    public operate replace(Request $request): Response
    {
        return response(Person::updateOrFail($request->id, $request->all()));
    }
}
Enter fullscreen mode

Exit fullscreen mode


Now our replace motion simplification is completed.

Comfortable coding!

The Article was Inspired from tech community site.
Contact us if this is inspired from your article and we will give you credit for it for serving the community.

This Banner is For Sale !!
Get your ad here for a week in 20$ only and get upto 10k Tech related traffic daily !!!

Leave a Reply

Your email address will not be published. Required fields are marked *

Want to Contribute to us or want to have 15k+ Audience read your Article ? Or Just want to make a strong Backlink?