Skip to content
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

Load relation without loading foreign key #16

Closed
rambii opened this issue Jun 13, 2017 · 12 comments
Closed

Load relation without loading foreign key #16

rambii opened this issue Jun 13, 2017 · 12 comments

Comments

@rambii
Copy link
Contributor

rambii commented Jun 13, 2017

I have the following relation:
User has many devices, and a device belongs to a user.
User has an id.
And a device has an user_id.

The following query will return the device information as desired:

{
  users {
    data {
      id
      firstname
      devices {
        id
      }
    }
  }
}

This query wont find any information devices (when leaving out the id):

{
  users {
    data {
      
      firstname
      devices {
        id
      }
    }
  }
}

Is this part of the design?
Or is there a way where I don't need to query the foreign key (user.id) explicitly?

@rebing
Copy link
Owner

rebing commented Jun 14, 2017

Make sure you have the 'model' value set in $attributes for both UserType and DeviceType, as shown here: https://github.com/rebing/graphql-laravel#creating-a-query

Also, make sure Device Model has defined its primary key (check the Eloquent Model class):
protected $primaryKey = 'user_id'

@rambii
Copy link
Contributor Author

rambii commented Jun 14, 2017

The $attributes value is set in both types.

Did you mean to write protected $primaryKey = 'user_id' for the User Model instead of the Device Model?
I updated the $primary_key in the models and tried various values but it does not work.

The attributes are also defined in the relation - why do I need to define the $primaryKey as well? This would also not work in case the model has multiple primaryKey depending on different relations. The relations look like this:

class Device extends Model {
    public function user()
    {
        return $this->belongsTo('App\User', 'account_id');
    }
}
class User extends Authenticatable {
    public function devices()
    {
        return $this->hasMany('App\Device', 'account_id');
    }
}

@rebing
Copy link
Owner

rebing commented Jun 14, 2017

Looking at your relation, it seems like User's primary key is account_id, not id, as you said earlier. The package uses the $primaryKey attribute to automatically select the correct keys for relations and they need to be defined in the Model, if they are not the default value (id).

@rambii
Copy link
Contributor Author

rambii commented Jun 14, 2017

account_id is the attribute in Devices. User has only an id-attribute.

This still does not work:

class User extends Authenticatable {
    protected $primaryKey = 'account_id';

    public function devices()
    {
        return $this->hasMany('App\Device', 'account_id');
    }
}

@rebing
Copy link
Owner

rebing commented Jun 14, 2017

Does account_id reference id on user table? If account_id is the primary key on device table, then its model needs to declare the protected $primaryKey = 'account_id', not the User model.

Can you show me those 2 database tables and their foreign keys?

@rambii
Copy link
Contributor Author

rambii commented Jun 14, 2017

I appreciate your help!

So the structure is as follows.
The reference is: tl_device.account_id = tl_member.id

User Table:

CREATE TABLE `tl_member` (
  `id` int(10) UNSIGNED NOT NULL,
  `firstname` varchar(255) NOT NULL DEFAULT '',
  ...
) 

User Model:

class User extends Authenticatable
{
    protected $table = 'tl_member';

    // protected $primaryKey = 'account_id'; // adding this will not work

    public function devices()
    {
        return $this->hasMany('App\Device', 'account_id');
    }
    
    ...
}

Device Table:


CREATE TABLE `tl_device` (
  `id` int(10) UNSIGNED NOT NULL,
  `address` bigint(11) UNSIGNED DEFAULT NULL,
  `account_id` int(10) UNSIGNED DEFAULT NULL,
  ...
)

Device Model:

class Device extends Model
{
    // protected $primaryKey = 'address'; // adding this will not work

    protected $table = 'tl_device';

    public function user()
    {
        return $this->belongsTo('App\User', 'account_id');
    }

    ...
}

@rebing
Copy link
Owner

rebing commented Jun 14, 2017

I'm sorry, but I can't find any mistake :( Did you try it without pagination? Are you returning GraphQL::paginate('user') with the query? You can post the full Query and maybe I'll find what's wrong

@rambii
Copy link
Contributor Author

rambii commented Jun 15, 2017

I turned off the pagination by defining the type in the UserQuery as Type::listOf(GraphQL::type('User'));

This will work as expected and return the information I want for the device without needing to query the id of the user as well.

{
  users {
    id                    // will also as intended work without this line
    firstname
    devices {
      id
    }
  }
}

Do you have an idea why this wont work any more with pagination?

@rebing
Copy link
Owner

rebing commented Jun 15, 2017

You are correct, it's not working correctly with pagination!

The mistake is probably somewhere inside the SelectFields class, but I currently don't have time to find it. You can try to solve it yourself and submit a PR or just use the current workaround and attach the id :/

@rambii
Copy link
Contributor Author

rambii commented Jun 15, 2017

Thanks for the hint. I'll look into in when I find the time.

@rebing
Copy link
Owner

rebing commented Jul 5, 2017

#23

@rebing rebing closed this as completed Jul 5, 2017
@thephucit
Copy link

Same issue, relations belongsTo does not return data

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

3 participants