Reputation: 8247
This seems to be a very easy problem to solve but apparently I haven't been able to think straight or look at the right place.
Say I have a schema, where columns are named in snake_case, by convention, e.g. branch_id
.
Normally, if the data is coming from a Phoenix form, you'd have the keys of the data corresponding exactly to the keys of the schema, so that you can write %MyStruct{} |> cast(attrs, [:branch_id])
etc.
However, in my JSON API, the incoming JSON object would have keys in camelCase, e.g. "branchId"
.
Is there any function from Ecto.Changeset
that I can use to conveniently correspond such keys from the incoming data to the columns in my schema?
An obvious solution would be to (in the controller,) Enum.map
over the incoming JSON first, use Macro.underscore
to convert the keys, and collect the result back into a map, before passing it to the changeset
function. However that would seem to be really extraneous and inefficient.
This is not only limited to the situation of snake_case vs. camelCase, but potentially any situation where the key looks different from the intended column name.
Upvotes: 0
Views: 594
Reputation: 430
If you are writing the client sending the JSON to your API, require that your API call JSON keys are snake_case to match the API endpoint.
The Macro.camelize
and Macro.underscore
functions are also not suitable for certain cases since they do not support unicode or invalid-in-Elixir-identifier characters, so you may want to look into Case2 if you want to accept camelCase and mutate into snake_case.
You could implement recase conditionally, e.g. if you receive a request with camelCase keys, Enum.map
or Enum.filter
and recase, but in most cases it is best to just spec your client API calls to match your backend API endpoints
Edit: changed Recase ref to Case2 since Recase apparently can't handle unicode either :P
Upvotes: 1