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

add virtual fields list to schema reflection #3133

Closed

Conversation

azhi
Copy link

@azhi azhi commented Oct 1, 2019

Schema.__schema__(:virtual_fields) should return list of all virtual
fields defined in Schema

As far as I can see, most of the other schema reflection data is used within ecto. List of virtual fields is not used within ecto, but it might be useful for users of ecto (at least it would be useful for me :)).

`Schema.__schema__(:virtual_fields)` should return list of all virtual
fields defined in `Schema`
@josevalim
Copy link
Member

josevalim commented Oct 1, 2019 via email

@azhi
Copy link
Author

azhi commented Oct 1, 2019

Yeah, there is a way to solve this outside of Ecto, but minimal working implementation for test schema looks like this:
((Schema.__struct__ |> Map.delete(:__meta__) |> Map.delete(:__struct__) |> Map.keys()) -- Schema.__schema__(:fields)) -- Schema.__schema__(:associations)

It looks like you should be able just to filter out fields and get a list of virtual fields, but in practice you need to deal with stuff like __meta__, __struct__, associations, embeds - and it ends up not looking good.
Another argument is that a list of things in struct you need to filter out depends heavily on Ecto. Right now it's __meta__, __struct__, associations and embeds (if I didn't miss anything), but if Ecto introduces new hypothetical field type that isn't DB field or one of the above - suggested code will break and consider it a virtual field.
Having this inside Ecto will add a nice explicit way of retrieving actual list of virtual fields.

As about broader use case without going in too much detail - I'm writing graphql API in elixir using absinthe, and want to write a middleware that would resolve virtual and non-virtual fields differently.

@josevalim
Copy link
Member

Do you need to have a list of all fields upfront or do you need to know if a field is a virtual field or not for a given struct? Those are slightly different. Another way to phrase this is: do you need to know this list at compile time or runtime?

@azhi
Copy link
Author

azhi commented Oct 2, 2019

For my specific use case runtime is good enough - it will have the cost of doing this check for every field, but it shouldn't be a big problem. If, however, this info is available at compile time, I can use it at compile time and optimize that way (absinthe has a nice feature that allows easily moving this stuff to compile time).

@josevalim
Copy link
Member

josevalim commented Oct 3, 2019 via email

@josevalim josevalim closed this Oct 3, 2019
@v0idpwn
Copy link
Member

v0idpwn commented Aug 18, 2021

Could we add this now? I'm on need. I'm willing to implement it if you think it is a good idea.

I'm working with a library that has an abstraction over embedded schemas + changesets. It relies on reflection in runtime and it would benefit from reading virtual fields.

@josevalim
Copy link
Member

josevalim commented Aug 19, 2021

Is the __changeset__ function not enough?

@v0idpwn
Copy link
Member

v0idpwn commented Aug 19, 2021

It works! I thought it was private API.

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

Successfully merging this pull request may close these issues.

None yet

3 participants