Skip to content

Commit

Permalink
Added support for creation of associated conversations with message v…
Browse files Browse the repository at this point in the history
…ia params
  • Loading branch information
begedin committed Dec 15, 2017
1 parent 44e53c1 commit 3d05903
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 6 deletions.
19 changes: 19 additions & 0 deletions lib/code_corps/messages/conversations.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
defmodule CodeCorps.Messages.Conversations do
@moduledoc ~S"""
Subcontext aimed at managing `CodeCorps.Conversation` records aimed at a
specific user belonging to a `CodeCorps.Message`.
"""

alias Ecto.Changeset

alias CodeCorps.{Conversation}

@doc false
@spec create_changeset(Conversation.t, map) :: Ecto.Changeset.t
def create_changeset(%Conversation{} = conversation, %{} = attrs) do
conversation
|> Changeset.cast(attrs, [:user_id])
|> Changeset.validate_required([:user_id])
|> Changeset.assoc_constraint(:user)
end
end
5 changes: 5 additions & 0 deletions lib/code_corps/messages/messages.ex
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ defmodule CodeCorps.Messages do
def create(%{} = params) do
%Message{}
|> Message.changeset(params)
|> Changeset.cast(params, [:author_id, :project_id])
|> Changeset.validate_required([:author_id, :project_id])
|> Changeset.assoc_constraint(:author)
|> Changeset.assoc_constraint(:project)
|> Changeset.cast_assoc(:conversations, with: &Messages.Conversations.create_changeset/2)
|> Repo.insert()
end

Expand Down
2 changes: 1 addition & 1 deletion lib/code_corps_web/controllers/conversation_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ defmodule CodeCorpsWeb.ConversationController do
}

action_fallback CodeCorpsWeb.FallbackController
plug CodeCorpsWeb.Plug.DataToAttributes
plug CodeCorpsWeb.Plug.DataToAttributes, %{"conversation" => "conversations"}
plug CodeCorpsWeb.Plug.IdsToIntegers

@spec index(Conn.t, map) :: Conn.t
Expand Down
6 changes: 3 additions & 3 deletions lib/code_corps_web/controllers/message_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ defmodule CodeCorpsWeb.MessageController do
}

action_fallback CodeCorpsWeb.FallbackController
plug CodeCorpsWeb.Plug.DataToAttributes
plug CodeCorpsWeb.Plug.DataToAttributes, %{"conversation" => "conversations"}
plug CodeCorpsWeb.Plug.IdsToIntegers

@spec index(Conn.t, map) :: Conn.t
Expand All @@ -23,7 +23,7 @@ defmodule CodeCorpsWeb.MessageController do
@spec show(Conn.t, map) :: Conn.t
def show(%Conn{} = conn, %{"id" => id}) do
with %User{} = current_user <- conn |> CodeCorps.Guardian.Plug.current_resource,
%Message{} = message <- Message |> Repo.get(id),
%Message{} = message <- Message |> Repo.get(id) |> preload(),
{:ok, :authorized} <- current_user |> Policy.authorize(:show, message, %{}) do
conn |> render("show.json-api", data: message)
end
Expand All @@ -40,7 +40,7 @@ defmodule CodeCorpsWeb.MessageController do
end
end

@preloads [:author, :project]
@preloads [:author, :project, :conversations]

def preload(data) do
Repo.preload(data, @preloads)
Expand Down
22 changes: 20 additions & 2 deletions lib/code_corps_web/plugs/data_to_attributes.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,31 @@ defmodule CodeCorpsWeb.Plug.DataToAttributes do
def init(opts), do: opts

@spec call(Conn.t, Keyword.t) :: Plug.Conn.t
def call(%Conn{params: %{"data" => data} = params} = conn, _opts) do
def call(%Conn{params: %{"data" => data} = params} = conn, many_mappings) do
attributes =
params
|> Map.delete("data")
|> Map.merge(data |> JaSerializer.Params.to_attributes)
|> Map.delete("included")
|> Map.merge(params |> parse_data)
|> Map.merge(params |> parse_included(many_mappings))
|> IO.inspect

conn |> Map.put(:params, attributes)
end
def call(%Conn{} = conn, _opts), do: conn

defp parse_data(%{"data" => data}), do: data |> JaSerializer.Params.to_attributes
defp parse_data(%{}), do: %{}

defp parse_included(%{"included" => included}, many_mappings) do
included |> Enum.reduce(%{}, fn (%{"data" => %{"type" => type}} = params, parsed) ->
attributes = params |> parse_data()

case many_mappings |> Map.has_key?(type) do
true -> parsed |> Map.update(many_mappings[type], [attributes], &List.push(&1, attributes))
false -> parsed |> Map.put(type, attributes)
end
end)
end
defp parse_included(%{}, _), do: %{}
end
2 changes: 2 additions & 0 deletions lib/code_corps_web/views/message_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ defmodule CodeCorpsWeb.MessageView do

has_one :author, type: "user", field: :author_id
has_one :project, type: "project", field: :project_id

has_many :conversations, serializer: CodeCorpsWeb.ConversationView, identifiers: :always
end

0 comments on commit 3d05903

Please sign in to comment.