diff --git a/lib/myapp/data/reply.ex b/lib/myapp/data/reply.ex index d49660a..01142ba 100644 --- a/lib/myapp/data/reply.ex +++ b/lib/myapp/data/reply.ex @@ -30,15 +30,15 @@ defmodule MyApp.Data.Reply do |> validate_required([:content]) end - @spec insert_reply(map) :: {:ok, map} | {:error, map} - def insert_reply(params) do + @spec insert(map) :: {:ok, map} | {:error, map} + def insert(params) do insert_changeset(%Data.Reply{}, params) |> Repo.insert |> Data.Util.process_insert_or_update end - @spec user_update_reply(map) :: {:ok, map} | {:error, map} - def user_update_reply(params) do + @spec user_update(map) :: {:ok, map} | {:error, map} + def user_update(params) do id = Map.get(params, "id") user_id = Map.get(params, "user_id") diff --git a/lib/myapp/data/thread.ex b/lib/myapp/data/thread.ex index de35d25..3959334 100644 --- a/lib/myapp/data/thread.ex +++ b/lib/myapp/data/thread.ex @@ -1,6 +1,7 @@ defmodule MyApp.Data.Thread do use Ecto.Schema import Ecto.Changeset + import Ecto.Query alias MyApp.Repo alias MyApp.Data @@ -15,6 +16,9 @@ defmodule MyApp.Data.Thread do field :sticky, :boolean, default: false field :locked, :boolean, default: false field :edited, :boolean, default: false + has_many :replies, Data.Reply + has_one :user, Data.User, foreign_key: :id, references: :user_id + has_one :last_reply, Data.User, foreign_key: :id, references: :last_reply_id timestamps() end @@ -40,14 +44,56 @@ defmodule MyApp.Data.Thread do |> validate_required([:content]) end - def insert_thread(params) do + def get(thread_id) do + query = from t in Data.Thread, + where: t.id == ^thread_id, + preload: [:user, :last_reply, :replies] + + Repo.one(query) + |> process_get + end + + def get_collection(category_id) do + query = from t in Data.Thread, + select: map(t, [ + :id, + :user_id, + :updated_at, + :inserted_at, + :sticky, + :locked, + :last_reply_id, + :edited, + :content, + :category_id, + user: [:id, :battletag], + last_reply: [:id, :battletag], + ]), + where: [category_id: ^category_id], + preload: [:user, :last_reply] + + if category_id != nil do + Repo.all(query) + |> process_get + else + {:error, "category_id required"} + end + end + + defp process_get(data) when is_nil(data), do: {:error, "Not found"} + defp process_get(data) when not is_nil(data), do: {:ok, data} + + @spec insert(map) :: {:ok, map} | {:error, map} + def insert(params) do insert_changeset(%Data.Thread{}, params) |> Repo.insert + |> remove_associations |> Data.Util.process_insert_or_update end - @spec user_update_thread(map) :: {:ok, map} | {:error, map} - def user_update_thread(params) do + # update thread for user permission + @spec user_update(map) :: {:ok, map} | {:error, map} + def user_update(params) do id = Map.get(params, "id") user_id = Map.get(params, "user_id") @@ -65,7 +111,10 @@ defmodule MyApp.Data.Thread do defp process_user_update(thread, params) when not is_nil(thread) do user_update_changeset(thread, params) |> Repo.update + |> remove_associations |> Data.Util.process_insert_or_update end + defp remove_associations({err, data}), do: {err, Map.drop(data, [:user, :replies, :last_reply])} + end diff --git a/lib/myapp_web/controllers/category_controller.ex b/lib/myapp_web/controllers/category_controller.ex index 373e4e3..68f0682 100644 --- a/lib/myapp_web/controllers/category_controller.ex +++ b/lib/myapp_web/controllers/category_controller.ex @@ -5,10 +5,20 @@ defmodule MyAppWeb.CategoryController do @spec get_collection(map, map) :: any def get_collection(conn, _params) do - output = Data.Category.get_categories() + output = get_categories() conn |> put_status(200) |> Response.json(output) end + # cache categories end point because the data won't change after server start + defp get_categories() do + case Cachex.get(:myapp, "categories") do + {:ok, data} -> data + {:missing, _} -> + data = Data.Category.get_categories() + Cachex.set(:myapp, "categories", data) + data + end + end end diff --git a/lib/myapp_web/controllers/reply_controller.ex b/lib/myapp_web/controllers/reply_controller.ex index d0fd1d6..4753abc 100644 --- a/lib/myapp_web/controllers/reply_controller.ex +++ b/lib/myapp_web/controllers/reply_controller.ex @@ -11,7 +11,7 @@ defmodule MyAppWeb.ReplyController do {output, status} = params |> Map.put("user_id", user_id) - |> Data.Reply.insert_reply + |> Data.Reply.insert |> Response.put_resp conn @@ -27,7 +27,7 @@ defmodule MyAppWeb.ReplyController do {output, status} = params |> Map.put("user_id", user_id) - |> Data.Reply.user_update_reply + |> Data.Reply.user_update |> Response.put_resp conn diff --git a/lib/myapp_web/controllers/thread_controller.ex b/lib/myapp_web/controllers/thread_controller.ex index ed6260b..d58754c 100644 --- a/lib/myapp_web/controllers/thread_controller.ex +++ b/lib/myapp_web/controllers/thread_controller.ex @@ -11,7 +11,7 @@ defmodule MyAppWeb.ThreadController do {output, status} = params |> Map.put("user_id", user_id) - |> Data.Thread.insert_thread + |> Data.Thread.insert |> Response.put_resp conn @@ -27,7 +27,7 @@ defmodule MyAppWeb.ThreadController do {output, status} = params |> Map.put("user_id", user_id) - |> Data.Thread.user_update_thread + |> Data.Thread.user_update |> Response.put_resp conn @@ -35,4 +35,28 @@ defmodule MyAppWeb.ThreadController do |> Response.json(output) end + @spec get_collection(map, map) :: any + def get_collection(conn, params) do + + {output, status} = params["category_id"] + |> Data.Thread.get_collection + |> Response.put_resp + + conn + |> put_status(status) + |> Response.json(output) + end + + @spec get(map, map) :: any + def get(conn, params) do + + {output, status} = params["id"] + |> Data.Thread.get + |> Response.put_resp + + conn + |> put_status(status) + |> Response.json(output) + end + end diff --git a/lib/myapp_web/router.ex b/lib/myapp_web/router.ex index 0924cab..dc6239b 100644 --- a/lib/myapp_web/router.ex +++ b/lib/myapp_web/router.ex @@ -36,6 +36,9 @@ defmodule MyAppWeb.Router do end scope "/thread" do + get "/", ThreadController, :get_collection + get "/:id", ThreadController, :get + # authenticated routes pipe_through [:user_auth] post "/", ThreadController, :insert diff --git a/test/myapp/data/thread_test.exs b/test/myapp/data/thread_test.exs index d665724..af7458f 100644 --- a/test/myapp/data/thread_test.exs +++ b/test/myapp/data/thread_test.exs @@ -12,24 +12,24 @@ defmodule MyApp.Data.ThreadTest do } end - test "insert_thread: try to insert with no parameters" do - assert insert_thread(%{}) == {:error, + test "insert: try to insert with no parameters" do + assert insert(%{}) == {:error, [%{title: "can't be blank"}, %{category_id: "can't be blank"}, %{content: "can't be blank"}, %{user_id: "can't be blank"}]} end - test "insert_thread: insert as invalid user" do - assert insert_thread(new_thread(9238748)) == {:error, [%{user_id: "does not exist"}]} + test "insert: insert as invalid user" do + assert insert(new_thread(9238748)) == {:error, [%{user_id: "does not exist"}]} end - test "insert_thread: insert as invalid category_id" do + test "insert: insert as invalid category_id" do {:ok, user} = new_user() - assert insert_thread(new_thread(user.id, 2342342343)) == {:error, [%{category_id: "does not exist"}]} + assert insert(new_thread(user.id, 2342342343)) == {:error, [%{category_id: "does not exist"}]} end test "new thread should be inserted" do {:ok, user} = new_user() - {:ok, thread} = insert_thread(new_thread(user.id)) + {:ok, thread} = insert(new_thread(user.id)) assert thread.title == "test title" assert thread.category_id == 1 assert thread.user_id == user.id