laravel-responder icon indicating copy to clipboard operation
laravel-responder copied to clipboard

Exception when using relations with snake_cases attribute names

Open igorparrabastias opened this issue 6 years ago • 1 comments

Hi. You are cameCasing relation attribute names in several parts, for example:

    /**
     * Eager load all requested relations except the ones defined as an "include" method
     * in the transformers. We also strip away any parameters from the relation name
     * and normalize relations by swapping "null" constraints to empty closures.
     *
     * @param  mixed                                                          $data
     * @param  array                                                          $requested
     * @param  \Flugg\Responder\Transformers\Transformer|callable|string|null $transformer
     * @return void
     */
    protected function eagerLoadRelations($data, array $requested, $transformer)
    {
        $relations = collect(array_keys($requested))->reduce(function ($eagerLoads, $relation) use ($requested, $transformer) {
            $identifier = camel_case($this->stripParametersFromRelation($relation)); // <--------- camel_case

            if (method_exists($transformer, 'include' . ucfirst($identifier))) {
                return $eagerLoads;
            }

            return array_merge($eagerLoads, [$identifier => $requested[$relation] ?: function () { }]);
        }, []);

        $data->load($relations);
    }

ref: vendor/flugger/laravel-responder/src/TransformBuilder.php

    /**
     * Resolve a relation from a model instance and an identifier.
     *
     * @param  \Illuminate\Database\Eloquent\Model $model
     * @param  string                              $identifier
     * @return mixed
     */
    protected function resolveRelation(Model $model, string $identifier)
    {
        $identifier = camel_case($identifier); // <--------- camel_case
        $relation = $model->$identifier;

        if (method_exists($this, $method = 'filter' . ucfirst($identifier))) {
            return $this->$method($relation);
        }

        return $relation;
    }

ref: vendor/flugger/laravel-responder/src/Transformers/Concerns/HasRelationships.php

This is causing problems with snake_cases attribute names, for example I have:

    public function qr_codes()
    {
        return $this->hasMany(QrCode::class)->orderBy('id');
    }

Maybe you could try snakeAttributes.

BTW: This is a marvellous package. This is the unique issue I have found, All the rest is working magically.

igorparrabastias avatar Apr 13 '18 15:04 igorparrabastias

Hey @NomikOS! The camel-casing of the relations were added not too long ago, in an attempt to allow people to output relationships as snake case from the transformer while still fetching the camel cased relations from the model (https://github.com/flugger/laravel-responder/issues/85). This was added on the basis that all relation-methods are camel cased, which is not the case in your case.

I'll look more closely into the snakeAttributes property and see if this could be done a better way. Oh, and thanks for the kind words, appreciated!

flugg avatar Apr 17 '18 09:04 flugg