geneeblack / graphql_model_mapper

This gem extends ActiveRecord::Base to facilitate generation of GraphQL objects based on your ActiveRecord models
MIT License
17 stars 2 forks source link

Feature support - model/attribute aliases #15

Open geneeblack opened 7 years ago

geneeblack commented 7 years ago

related to #4

A request was made to support aliasing of models and attributes in #4, this discussion is ongoing and broken out for clarity

geneeblack commented 7 years ago

Question whether this is needed or if it can be accomplished through GraphQL language aliases

i.e. example of using GraphQL aliases

screen shot 2017-11-15 at 4 11 13 am

AndyKriger commented 6 years ago

there are times when one does not want to expose the details of the model also, the aliases as we use them server two purposes...1) return a field with a different name, 2) a convenience for drilling down into object associations (ex: we have associated objects that have tokens...A.B.C.token and we alias this to {C_token: [:a, :b, :c, :token]})

geneeblack commented 6 years ago

I can see where that might be useful, at the model level it should be pretty much a straight shot to implement. Although I may be underestimating the effort, since if you are trying to obfuscate a name it would also apply to the type names for the model with the downside that if creating multiple alias names you could end up with multiple types and their definitions based on the underlying model... ugh. If you are wanting to create multiple attribute aliases for the same model it would also involve input/output type definition config for each alias, also ugh.

There should be some way similar to using GraphQL fragments and aliases that you could just chain off the top level model without having to create a whole new base definition although that wouldn't cover the types, let me think a bit about it. Maybe it might be able to be done with custom types and/or some type of inheritance chain without trying to boil the ocean a second time with the model. I could be completely wrong though and maybe aliasing would not be a big issue and I'm being too skeptical.

geneeblack commented 6 years ago

note: another consequence of aliases could be the potential for type name collisions

geneeblack commented 6 years ago

I guess I've made the assumption that when using aliases that you would want the capability to establish multiple aliases with different input/output interfaces for each alias. Just to make sure I'm thinking of the correct scope, is this what you envision? i.e. Multiple query objects for a model differing by their alias which would also be applied to their i/o types?

geneeblack commented 6 years ago

I now realize why you wanted to wrap the query/mutations up into a top level wrapper, to employ an alias/multiple aliases this would somewhat be necessary. It does get easier to see how this might work with a top level object which contains its alias name and its own subset of query/mutation/and type declaration references, i.e.

graphql_declare alias: "prettyTableName", types:{}, query:{}, create: {}, update: {}, delete: {}

geneeblack commented 6 years ago

maybe this could be done separately, while supporting simple declarations for ease of entry, also support package declarations for more complex scenarios with the package declarations simply feeding off of the base functionality of the simple declarations except the simple declarations would never directly support aliasing.. hmm have to consider whether it is feasible or just introduces too many vectors

geneeblack commented 6 years ago

also whether it makes sense to bring the types back under the object they reference, i.e

query:{...types:{input:{}, output:{}, aliases:[]}}

a lot of restructuring, but I think it would be feasible and necessary in order to support aliasing

geneeblack commented 6 years ago

just thought of an issue, when building the associations, which alias name would be applicable for the association type? If multiple aliases are available on a model then how to know which aliased type the association uses when accessing it from another aliased model?

geneeblack commented 6 years ago

@AndyKriger Given the assumption that use of aliases would allow multiple instances of a model expressed as a GraphQL type and the following model definition is expressed:

class person
    has_many :cars
    graphql_query alias: :driver
    graphql_query alias: :operator
end

class car
    belongs_to :person
    graphql_query alias: :automobile
    graphql_query alias: :vehicle
end

In this case when building out the GraphQL type representation for person alias: :driver, how to know which type name to use for association cars? Do I use the alias :automobile (AutomobileQueryOutputType.to_list_type) for type naming or type :vehicle (VehicleQueryOutputType.to_list_type)?

Conversely when building out either car alias, which person reference to use to build out the types?

Of course this is a moot point if the intention is not to allow multiple alias types to be expressed on a model.

geneeblack commented 6 years ago

@AndyKriger short term you could set up an interface model pointing to an updatable view with model class name and column names along with associations with the desired aliases until I get around to providing alias capability in this gem.