jeudi 19 novembre 2015

Laravel 5.1 / Eloquent: Polymorphic morphMany not finding results

Problem
morphMany is not returning any results. We have an images MySQL table that is referenced by four other MySQL tables including user_characters. Even though there are many matching images for user_characters, the returned JSON when calling "http://ift.tt/1MWpBTO" (routed to UserCharactersController@index) looks like:

   {
        "data": [
            {
                "id": "14478963213628aa3ea8eeb7146fcae1",
                "user_id": "14478963196067aa80d6351f6ecd9ae1",
                "active": true,
                "updated_at": "2015-11-19 01:25:21",
                "images": {
                    "data": []
                }
            }
        ]
    }


It should look like:

        {
        "data": [
            {
                "id": "14478963213628aa3ea8eeb7146fcae1",
                "user_id": "14478963196067aa80d6351f6ecd9ae1",
                "active": true,
                "updated_at": "2015-11-19 01:25:21",
                "images": {
                    "data": [
                        {
                            'id'                    => "14478963213628aa3ea8eeb7146fbee1",
                            'reference_id'          => "14478963213628aa3ea8eeb7146fcae1",
                            'reference_type'        => "app\UserCharacter",
                            'created_by_user_id'    => "14478963196067aa80d6351f6ecd9ae1",
                            'order'                 => 0,
                            'updated_at'            => "2015-11-19 01:25:21"
                        },
                        {
                            'id'                    => "14478963213628aa3ea8eeb7146fbee2",
                            'reference_id'          => "14478963213628aa3ea8eeb7146fcae1",
                            'reference_type'        => "app\UserCharacter",
                            'created_by_user_id'    => "14478963196067aa80d6351f6ecd9ae1",
                            'order'                 => 1,
                            'updated_at'            => "2015-11-19 01:25:21"
                        }
                    ]
                }
            }
        ]
    }



I would greatly appreciate any help you can offer in helping return the correct results. Thank you.



Framework
Laravel 5.1
Eloquent
Fractal



//MARK: CODE (8 Blocks)

user_characters Table (1/8)

    Schema::create('user_characters', function (Blueprint $table) 
    {
        $table->binary('id', 16);
        $table->binary('parent_character_id', 16);
        $table->binary('user_id', 16);
        $table->boolean('active')->default(false);
        $table->boolean('archived')->default(false);
        $table->timestamps();

        $table->primary('id');
        $table->foreign('parent_character_id')->references('id')->on('characters');
        $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
    });


images Table (2/8)

Schema::create('images', function (Blueprint $table) 
    {
        $table->binary('id', 16);
        $table->binary('reference_id', 16)->nullable();
        $table->string(); //Values are 'UserCharacter', I received a 502 error when I used 'app\UserCharacter'
        $table->binary('created_by_user_id', 16)->nullable();
        $table->tinyInteger('order');
        $table->timestamps();

        $table->primary('id');
        $table->foreign('created_by_user_id')->references('id')->on('users')->onDelete('set null');
    });


ApiController (3/8)

class ApiController extends Controller
    {
        public function __construct(Manager $fractal)
        {
            $this->fractal = $fractal;

            $this->fractal->parseIncludes(explode(',', Input::get('include')));
        }

        protected function respondWithCollection($collection, $callback)
        {
            ...
        }
    }


UserCharacterController (4/8)

class UserCharactersController extends ApiController
    {
        public function index()
        {
            $userCharacters = UserCharacter::take(10)->get();
            return $this->respondWithCollection($userCharacters, new UserCharacterTransformer());
        }
    }


UserCharacterTransformer (5/8)

class UserCharacterTransformer extends TransformerAbstract
    {
        protected $defaultIncludes = ['images'];

        public function transform(UserCharacter $userCharacter){
            return [
                'id'                    => bin2hex($userCharacter->id),
                'user_id'               => bin2hex($userCharacter->user_id),
                'active'                => (boolean) $userCharacter->active,
                'updated_at'            => $userCharacter->updated_at->toDateTimeString()
            ];
        }

        public function includeImages(UserCharacter $userCharacter){
            return $this->collection($userCharacter->images, new ImageTransformer());
        }
    }


ImageTransformer (6/8)

        class ImageTransformer extends TransformerAbstract
    {
        public function transform(Image $image){
            return [
                'id'                    => bin2hex($image->id),
                'reference_id'          => bin2hex($image->reference_id),
                'reference_type'        => $image->reference_type,
                'created_by_user_id'    => bin2hex($image->created_by_user_id),
                'order'                 => (int) $image->order,
                'updated_at'            => $image->updated_at->toDateTimeString()
            ];
        }
    }


UserCharacter::Model (7/8)

class UserCharacter extends Model
    {
        protected $morphClass = 'app\UserCharacter'; //tried with, and without this.  Switched it to 'UserCharacter' and received 502 error.

        protected $table = "user_characters";

        public $incrementing = false;

        protected $with = ['images'];

        protected $fillable = ['id', 'parent_character_id', 'user_id', 'active'];

        public function images(){
            return $this->morphMany('app\Image', 'reference');
        }
    }


Image::Model (8/8)

class Image extends Model
    {
        protected $table = "images";

        public $incrementing = false;

        protected $fillable = ['id', 'reference_id', 'created_by_user_id', 'order'];

        protected $types = [
            "usercharacter"     => "app\UserCharacter"
        ];

        public function getReferenceTypeAttribute($type) {
            //If empty, return null
            if(!$type) {
                return null;
            }

            // transform to lower case
            $type = strtolower($type);

            // to make sure this returns value from the array
            return array_get($this->types, $type, $type);
        }

        public function reference(){
            return $this->morphTo();
        }
    }



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire