-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
:map
type in Schemaless Changeset.cast/3
only accepts single type
#4271
Comments
I think if you are going to define the keys like that in the types then you could go with an embedded schema instead? |
It would be nice to do validations on schemaless embedded maps. In my case, I'm trying to validate the payload of a RESTful PATCH call. Creating schemas brings complexity to the code and also generates a primary key for the objects, which is not needed in certain cases. The current behavior of schemaless seems counterintuitive for type I also tried to implement casting with
|
Thanks for the context. I'm not too sure what to do atm but just a few things to note:
|
This is the important context! It is always best to describe the problem so it gives more space for solutions. :) I am happy to allow more nesting on schemaless changesets, but I don’t think it should be via the map type, especially since maps are often serialized as JSON which is a bit different from how other values are serialized to the database. one option would be to alllow |
@greg-rychlewski , Thanks for the notes!
That makes sense, I forgot that it could be used in schemas as well.
Great, despite the complexity, this could help me to go in the embedded schema direction. |
@josevalim Thanks, I'll make sure to add context from the begging.
Also, thanks for considering adding a child option for schemaless changesets. After thinking about it a bit more, I realized that besides connecting the feature with embeds, we would also have to consider how to target nested values with the validation functions. I guess we could pass a list of atoms, but this would bring a lot more complexity than I initially thought. Based on @greg-rychlewski's suggestion wouldn't mind going in the direction of embedded schemas. What do you think about adding a |
Sorry, I was on my phone, what I meant for
Notice that, for embedded schemas, we do this:
One possible option would be for us to change that to do this:
If we could make this work, then you could use "schemaless embeds" (we could improve the API ergonomics too). It was a while since we tried and we ran into corner cases, but it may be worth trying again. |
+1 from me |
@josevalim thanks for explaining the lower level implementation of embeds. Yeah, this sounds like something we could use for our problem. I'm a regular user of the library but haven't contributed yet. If there is anything I can help with, please let me know and I would be more than happy to make this happen. Thanks! |
Running into the very same issue from a different angle. I have some dynamic key/value pairs of questions that admins can create freely, and I "embed" customers values for these questions as a map into a db column and still need validations. Basically like a dynamic CMS. At this point I am totally lost because it seems I cannot |
Note you can use |
this actually is a nice idea, thanks @josevalim ! my problem is "just" that final part, where applying the changeset to the data struct it gets blanked out again and I end up with NULL values in my db :-( but kinda virtual embeds_one schema that has no fields (gets stuff at runtime) and I sync this to the actual map field within the changeset pipeline ... weird but might help :-) |
I found myself in a similar situation, but in our case the map is a schema, as it's being used in different places. I thought I could use something like: {%{}, %{foo: Ecto.ParameterizedType.init(Ecto.Embeded, cadinality: :one, field: :foo, related: Foo)}}
|> cast([:foo])
|> ... but I think that this pattern match ( def cast(%{__struct__: schema} = struct, %{cardinality: :one, related: schema}) do
is blocking us, as there is no |
:map
type in Schemaless Changeset.cast/3
only accepts single type.:map
type in Schemaless Changeset.cast/3
only accepts single type
Hello, I also encountered problem with using schemaless embeds. I wanted to cast and validate params from requests. But I also need to invoke This can be achieved via implementing But It'll be much simpler if we've got schemaless embeds out of the box. I forked and implemented dummy prototype but I'm not sure whether it is a valid approach according to the conversation. As it's not providing new flow for bare Also I haven't tested in with updating existing data, as for validation I always build new map. |
I would like to introduce another approach to the Ecto schemaless Changesets, as an avid user of this feature. Mostly, from what I can see, this feature is used to validate format of external inputs or mid-state structures that are passed along into the application internals. So, borrowing the idea of plumatic/schema for Clojure, which defines schemas as data, I tried to implement this to make a PoC on how easy would be to interact with deeply nested data structures, and from there, borns peri. What do you think about this "raw" idea to define schemaless changesets? Is that even possible or makes any sense? |
I implemented the original issue proposal here. As anticipated, this approach causes a few problems:
Embeds don't have such limitations, but make the API significantly more cumbersome. |
Elixir version
1.14.4
Database and Version
n/a
Ecto Versions
3.9.5
Database Adapter and Versions (postgrex, myxql, etc)
n/a
Current behavior
This works, and it means that all keys in the map must be strings.
This also works to detect non-string fields within the nested map.
However, when we try to define a specific type of the nested key, an error is raised.
It seems we are limited to uniform types exclusively.
Expected behavior
We should be able to define custom types for each key in the map. e.g:
Thank you
The text was updated successfully, but these errors were encountered: