Giter Site home page Giter Site logo

laravel-resources's People

Contributors

dees040 avatar dependabot-preview[bot] avatar mindabartosz avatar thomas-veen avatar thomasowow avatar youneselbarnoussi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

laravel-resources's Issues

Dynamic resource response in `ResourceController`

Currently when a custom manager method needs to be called to only retrieve and display its contents, a custom controller needs to be created. 90% of the cases the only difference between the ResourceController and this custom controller is the method that is being called to retrieve these results.

Eg:

class PostController extends ResourceController
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     *
     * @throws \Illuminate\Auth\Access\AuthorizationException
     */
    public function index()
    {
        $this->authorize('view', $this->resourceModelClass);

        $resourcesPaginated = $this->resourceManager->paginateForUser(currentUser()); // <- the only difference

        $resources = resource($resourcesPaginated, true);

        $resourcesPaginated->setCollection($resources->collection);

        return ok($resourcesPaginated);
    }
}

A suggestion would be to implement the __call method to allow a non Response type to be returned by all resource methods. The following pseudo example could make things a little more clearer:

class PostController extends ResourceController
{
    public function index()
    {
        // Instead of implementing all duplicate code we will just return a
        // LengthAwarePaginator type.
        return $this->resourceManager->paginateForUser(currentUser());
    }
}

class ResourceController
{
    public function __call()
    {
        // Call the authorization
        $this->authorizeForMethod($method);

        // We call the intended method. If it does not exist it should throw an
        // non existing method call exception like PHP does by default we do
        // not want to change this behaviour.
        $result = $this->$method(...);

        // We check if the $result is of instance response. If so we return this.
        if ($result instanceof Response) {
            return $result;
        }

        // Otherwise we will make a response with the results.
        else {
            // Depening on the method is being called we return different responses.
            return $this->respondForMethod($method, $results);
        }
    }
}

This change will result in less duplicate code in our controllers and keeps the possibility of returning a custom response.

Move ResourceController model actions to separate methods.

As mentioned in #7 we constantly have to copy the whole method when only changing the model "action" part. The model action could be retrieving, storing, updating...

A new proposal is to separate these action calls in new methods so the overwriting is minimal. The following example would make this clearer.

// ResourceController
public function index()
{
    ... default stuff

    $models = $this->indexModel();

    ... default stuff
}

public function indexModel()
{
    return $this->resourceModelClass::paginate();
}

// My custom controller
public function indexModel()
{
    return $this->resourceModelClass::with('relation')->paginate();
}

Resource controller authorize

Currently the ResourceController@authorize uses $this->resourceModelClass to find a policy. However the model that is used to find a policy might not always be the resourceModelClass and thus might result in a wrong authorization.

Suggestion to change code:

public function authorize($ability, $arguments = [])
{
    $model = is_array($arguments)
        ? Arr::first($arguments)
        : $arguments;

    // Do not try to authorize when policy does not exist.
    if (is_null(Gate::getPolicyFor($model))) {
        return;
    }

    return $this->traitAuthorize($ability, $arguments);
}

This code will use the model class that is actually authorized.

Do not extend from App namespaces.

Some classes extend from the App namespace. Example is that the ResourceController extends from App\Http\Controller class. Not sure if this is done in more than one location.

The classes should extend other classes provided by Laravel.

Modify ResourceController to allow storing multiple models at once

If we want to store multiple models at once, we can overwrite the storeModel method in ResourceController.

However, currently the store method will always return 1 single resource, due to this code:

$model = $this->storeModel($request);

$resource = resource($model);

return created($resource);

Todo:

  • Check whether the return of storeModel is a single resource or a collection. Return the correct JSON resource accordingly.

Make getModel work with getRouteKeyName

When a developer chooses to have a different route key name, eg: slug, the ResourceController@getModel will fail. getModel uses findOrFail wich uses the primaryKey property of the model.

Maybe use where($theRouteKeyName, $model)->firstOrFail()

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.