Skip to content
Merged
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 lib/code_corps_web/controllers/comment_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ defmodule CodeCorpsWeb.CommentController do

action_fallback CodeCorpsWeb.FallbackController
plug CodeCorpsWeb.Plug.DataToAttributes
plug CodeCorpsWeb.Plug.IdsToIntegers

@spec index(Conn.t, map) :: Conn.t
def index(%Conn{} = conn, %{} = params) do
Expand Down
10 changes: 7 additions & 3 deletions lib/code_corps_web/plugs/ids_to_integers.ex
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
defmodule CodeCorpsWeb.Plug.IdsToIntegers do
@moduledoc ~S"""
Converts id values (primary or relationships) in a conn params map into
integers, if applicable.
Converts `id` values in a `conn` parameters map into integers, if applicable.

The JSON API specification expects `id` values in resource objects to be
strings.

See http://jsonapi.org/format/#document-resource-object-identification
"""

alias Plug.Conn
Expand All @@ -22,7 +26,7 @@ defmodule CodeCorpsWeb.Plug.IdsToIntegers do

@spec convert_key_value(tuple) :: tuple
defp convert_key_value({key, value}) do
case key |> convert?() do
case convert?(key) do
true -> {key, value |> ensure_integer()}
false -> {key, value}
end
Expand Down
32 changes: 16 additions & 16 deletions test/support/json_api_helpers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,19 @@ defmodule CodeCorps.JsonAPIHelpers do
with attributes <- build_attributes(attrs),
relationships <- build_relationships(attrs)
do
build_payload(attributes, relationships)
%{
"data" => %{
"attributes" => attributes,
"relationships" => relationships
}
}
end
end

defp build_attributes(attrs) do
attrs
|> Enum.filter(&is_attribute(&1))
|> Enum.reduce(%{}, &insert_string_key(&1, &2))
|> Enum.reduce(%{}, &add_attribute(&1, &2))
end

defp build_relationships(attrs) do
Expand All @@ -19,11 +24,12 @@ defmodule CodeCorps.JsonAPIHelpers do
|> Enum.reduce(%{}, &Map.merge(&2, &1))
end

defp build_relationship({key, record}) do
with id <- record.id,
type <- model_name_as_string(record)
defp build_relationship({atom_key, record}) do
with id <- record.id |> to_correct_type(),
type <- record |> model_name_as_string(),
string_key = atom_key |> Atom.to_string
do
%{} |> Map.put(Atom.to_string(key), %{"data" => %{"id" => id, "type" => type}})
%{} |> Map.put(string_key, %{"data" => %{"id" => id, "type" => type}})
end
end

Expand All @@ -40,16 +46,10 @@ defmodule CodeCorps.JsonAPIHelpers do
|> String.downcase
end

defp insert_string_key({key, value}, map) do
with string_key <- Atom.to_string(key), do: Map.put(map, string_key, value)
defp add_attribute({key, value}, %{} = attrs) do
attrs |> Map.put(key |> Atom.to_string, value)
end

defp build_payload(attributes, relationships) do
%{
"data" => %{
"attributes" => attributes,
"relationships" => relationships
}
}
end
defp to_correct_type(value) when is_integer(value), do: value |> Integer.to_string
defp to_correct_type(value), do: value
end