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

Replace Arc.Ecto.Schema with importable Arc.Ecto.Changeset #110

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ erl_crash.dump
*.ez
.DS_Store
/doc
.elixir_ls
49 changes: 49 additions & 0 deletions lib/arc_ecto/changeset.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
defmodule Arc.Ecto.Changeset do
@spec cast_attachments(
Ecto.Schema.t() | Ecto.Changeset.t(),
:invalid | map(),
[String.t() | atom()],
Keyword.t()
) :: Ecto.Changeset.t()
def cast_attachments(changeset_or_data, params, allowed, options \\ []) do
scope = case changeset_or_data do
%Ecto.Changeset{} -> Ecto.Changeset.apply_changes(changeset_or_data)
%{__meta__: _} -> changeset_or_data
end

# Cast supports both atom and string keys, ensure we're matching on both.
allowed_param_keys = Enum.map(allowed, fn key ->
case key do
key when is_binary(key) -> key
key when is_atom(key) -> Atom.to_string(key)
end
end)

arc_params = case params do
:invalid ->
:invalid
%{} ->
params
|> Arc.Ecto.Changeset.Helpers.convert_params_to_binary()
|> Map.take(allowed_param_keys)
|> Enum.reduce([], fn
# Don't wrap nil casts in the scope object
{field, nil}, fields -> [{field, nil} | fields]

# Allow casting Plug.Uploads
{field, upload = %{__struct__: Plug.Upload}}, fields -> [{field, {upload, scope}} | fields]

# If casting a binary (path), ensure we've explicitly allowed paths
{field, path}, fields when is_binary(path) ->
if Keyword.get(options, :allow_paths, false) do
[{field, {path, scope}} | fields]
else
fields
end
end)
|> Enum.into(%{})
end

Ecto.Changeset.cast(changeset_or_data, arc_params, allowed)
end
end
19 changes: 19 additions & 0 deletions lib/arc_ecto/changeset/helpers.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
defmodule Arc.Ecto.Changeset.Helpers do
@moduledoc false

@doc false
def convert_params_to_binary(params) do
Enum.reduce(params, nil, fn
{key, _value}, nil when is_binary(key) ->
nil

{key, _value}, _ when is_binary(key) ->
raise ArgumentError, "expected params to be a map with atoms or string keys, " <>
"got a map with mixed keys: #{inspect params}"

{key, value}, acc when is_atom(key) ->
Map.put(acc || %{}, Atom.to_string(key), value)

end) || params
end
end
71 changes: 0 additions & 71 deletions lib/arc_ecto/schema.ex

This file was deleted.

4 changes: 2 additions & 2 deletions test/schema_test.exs → test/changeset_test.exs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
defmodule ArcTest.Ecto.Schema do
defmodule ArcTest.Ecto.Changeset do
use ExUnit.Case, async: false
import Mock
import ExUnit.CaptureLog

defmodule TestUser do
use Ecto.Schema
import Ecto.Changeset
use Arc.Ecto.Schema
import Arc.Ecto.Changeset

schema "users" do
field :first_name, :string
Expand Down