Vincit / objection-graphql

GraphQL schema generator for objection.js
MIT License
307 stars 34 forks source link

extras in relationShipMappings not supported ? #51

Open BerndWessels opened 6 years ago

BerndWessels commented 6 years ago

Hi this documention says there can be extra columns in relationship tables - and they get mapped into the related models.

But its seems I can't use them in GraphQL Query? Is this possible, or can you please add it?

I also want to be able to provide a parameter to filter on that extra column.

graphql(graphQlSchema, `{
  users {
    id
    name
    accounts {
      id
      name
      somethingExtra
    }
  }
const {Model} = require('objection');

class User extends Model {
    static get tableName() {
        return 'user';
    }

    static get jsonSchema() {
        return {
            type: 'object',
            required: ['name'],

            properties: {
                id: {type: 'integer'},
                name: {type: 'string', minLength: 1, maxLength: 255},
            },
        };
    }

    static get relationMappings() {
        const Account = require('./account');

        return {

            accounts: {
                relation: Model.ManyToManyRelation,
                modelClass: Account,
                join: {
                    from: 'user.id',
                    through: {
                        from: 'user_account.user_id',
                        to: 'user_account.account_id',
                        extra: ['somethingExtra']
                    },
                    to: 'account.id',
                },
            },

        };
    }
}

module.exports = User;
timhuff commented 6 years ago

It won't be there if it's not in your schema.

BerndWessels commented 6 years ago

@timhuff what exactly do you mean? I thought the schema gets generated based on the models:

const graphQlSchema = graphQlBuilder()
  .model(User)
  .model(Account)
  .build();

Is it supposed to work and where in my schema should I put the extra columns that are on the link table? Will the generated GraphQL filters work for the extra columns too?

Would you be so kind to put a tiny example here?

Thank you

timhuff commented 6 years ago

Yea, sorry for being so terse there. I just meant to toss out the answer real quick and didn't take the time I should've.

As far as this library is concerned, if a property is not included in your json schema, it's not going to be available via the generated GraphQL API. The schema is how this library generates the API at all - so I was just pointing out "even if it did support extras, they wouldn't show up because its not part of your schema".

So then we get to the topic of selectFiltering - which is basically how the library only selects from the DB the props you specified in your query. This, conversely, means that if you specify it in your query, the API's going to attempt to grab it out of the DB (error: field does not exist). A way to get around this is to call .selectFiltering(false) on your schema builder but I would advise against it because then every query you'd make would be a select * from query.

I think you could use the pull request I just put in earlier today (didn't exist when I left my last comment) to get around this but I'm not positive. Its intention was to support virtual properties without the need to turn off select filtering... but I see no reason it wouldn't work for this purpose as well. If you take a look at the file at this link, you'll see an example of how to use that pull request. The property utilizing my pull request is birthYear (the other virtual property was being used by the "virtual properties work if you turn off select filtering" test, so I didn't want to touch it).

So, for your purpose, you'd just add the following to your model and then utilize my pull request

    static get virtualJsonSchemaProperties() {
        return {
            somethingExtra: { type: <data type of prop> }
        }
    }

If this ends up working out for you, I'd appreciate it if you'd come back here and let me know - this is an interesting use case for it.

timhuff commented 6 years ago

Oh, and as for the "will generated filters work" question... I'm not sure but I have the feeling they might.

BerndWessels commented 6 years ago

Great, thanks @timhuff

I will give it a try and report here later.

timhuff commented 6 years ago

@BerndWessels This end up working out for you?

BerndWessels commented 6 years ago

@timhuff Sorry, I am just back to work now and will try it now. Let you know soon.

timhuff commented 6 years ago

@BerndWessels Just letting you know that we reverted the merge I referenced here. Virtual attributes are properly supported now, though, so you might be able to add your extra to the virtualAttributes property in objection to get it to work.