Skip to content

Problem with belongsToMany relationship #21

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
adiachenko opened this issue Sep 5, 2016 · 2 comments
Closed

Problem with belongsToMany relationship #21

adiachenko opened this issue Sep 5, 2016 · 2 comments

Comments

@adiachenko
Copy link

adiachenko commented Sep 5, 2016

Note, that I am currently using 0.5.x-dev (as I'm working with Laravel 5.3) so the problem below may not apply to earlier versions of this package.

BelongsToMany relationships leads to the following Exception.

Next Illuminate\Database\QueryException: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'helios.model_model' doesn't exist (SQL: select `roles`.*, `model_model`.`model_id` as `pivot_model_id`, `model_model`.`created_at` as `pivot_created_at`, `model_model`.`updated_at` as `pivot_updated_at` from `roles` inner join `model_model` on `roles`.`id` = `model_model`.`model_id` where `model_model`.`model_id` = 1) in /var/www/helios/vendor/laravel/framework/src/Illuminate/Database/Connection.php:761

At first glance, it seems like the package can't figure out the name of pivot table and foreign key in accordance with Laravel naming conventions.

When I manually specify names (i.e. return $this->belongsToMany(\App\JsonApi\Roles\Model::class, 'role_user', 'id', 'role_id')->withTimestamps();), Exception is no longer thrown but I encounter another issue: $resource->roles should be a collection with multiple(!) items but I get the collection with only the very first one in response.

Below is the code that lead to this post.

Model

<?php

namespace App\JsonApi\Users;

use Illuminate\Database\Eloquent\Model as EloquentModel;

class Model extends EloquentModel
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'users';

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function roles()
    {
        return $this->belongsToMany(\App\JsonApi\Roles\Model::class)->withTimestamps();
    }
}

Schema

<?php

namespace App\JsonApi\Users;

use CloudCreativity\LaravelJsonApi\Schema\EloquentSchema;

class Schema extends EloquentSchema
{
    const RESOURCE_TYPE = 'users';

    /**
     * @var string
     */
    protected $resourceType = self::RESOURCE_TYPE;

    /**
     * Whether resource member names are hyphenated
     *
     * @var bool
     */
    protected $hyphenated = false;

    /**
     * The model attribute keys to serialize.
     *
     * @var array
     */
    protected $attributes = [
        'email',
        'first_name',
        'last_name',
    ];

    /**
     * Get resource links.
     *
     * @param object $resource
     * @param bool   $isPrimary
     * @param array  $includeRelationships
     * @return array
     */
    public function getRelationships($resource, $isPrimary, array $includeRelationships)
    {
        return [
            'roles' => [
                self::SHOW_SELF => true,
                self::SHOW_RELATED => true,
                self::DATA => $resource->roles,
            ],
        ];
    }
}

@lindyhopchris
Copy link
Member

@adiachenko I don't think this is a problem with this package. The package calls the methods on your model class, so it uses the relationships objects that are returned by those methods.

I wouldn't recommend putting the model classes in the JSON API namespaces. This is because Eloquent does a lot of "magic" based on the class names of models, and all your models will be called "Model".

Generally I put all the parts of constructing a JSON API within those JSON API namespaces - as basically JSON API is a "view" layer - i.e. a JSON representation of your application's models.

When it comes to the Eloquent models, I'd follow the Laravel convention and have them in a namespace (normally the "App" namespace), with each class called it's relevant name. In your example it should be User class, not Model.

You can see that in the demo app here:
https://github.com/cloudcreativity/demo-laravel-json-api/tree/laravel-5.3

Models are in the App namespace as per the Laravel convention, JSON API units are in the App\JsonApi namespace.

@adiachenko
Copy link
Author

@lindyhopchris Thank you for quick response. I'll try following different conventions to avoid unexpected problems with Eloquent then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants