~cosmicrose/liberator_example

liberator_example/lib/liberator_example_web/controllers/post_controller.ex -rw-r--r-- 2.4 KiB
d1401427Rosa Richter Reduce potential changelog merge conflicts 8 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
defmodule LiberatorExampleWeb.PostController do
  use Liberator.Resource

  alias LiberatorExample.Blog
  alias LiberatorExample.Blog.Post

  require Logger

  @impl true
  def allowed_methods(_), do: ["GET", "POST", "PUT", "DELETE"]

  @impl true
  def available_media_types(_), do: ["application/json"]

  @impl true
  def processable?(conn) do
    valid_param?(conn.params["post"], "title") and valid_param?(conn.params["post"], "content")
  end

  defp valid_param?(params, key) do
    if not is_nil(params) and Map.has_key?(params, key) do
      not is_nil(params[key])
    else
      true
    end
  end

  @impl true
  def exists?(conn) do
    id = conn.params["id"]

    if is_nil(id) do
      # Showing the index
      posts = Blog.list_posts()
      %{content: posts}
    else
      # Interacting with an individual post.
      case Blog.get_post(id) do
        nil -> false
        post -> %{content: post, new: false}
      end
    end
  end

  @impl true
  def delete!(conn) do
    {:ok, _post} = Blog.delete_post(conn.assigns[:content])
    true
  end

  @impl true
  def put!(conn) do
    # We already fetched this resource when we checked for it in `exists?/1`,
    # so we can just grab what we cached
    post = conn.assigns[:content]

    {:ok, updated_post} = Blog.update_post(post, conn.params["post"])

    # Update the content we're working with, because we will want to return it in a handler
    %{content: updated_post}
  end

  @impl true
  def post!(conn) do
    {:ok, post} = Blog.create_post(conn.params["post"])

    # Update the content we're working with, because we will want to return it in a handler
    %{
      content: post,
      location: LiberatorExampleWeb.Router.Helpers.post_url(conn, :show, post.id)
    }
  end

  @impl true
  def new?(conn) do
    Map.get(conn.assigns, :new, true)
  end

  @impl true
  def handle_ok(conn) do
    %{data: conn.assigns[:content]}
  end

  @impl true
  def handle_created(conn) do
    %{data: conn.assigns[:content]}
  end

  @impl true
  def handle_not_found(_conn) do
    %{errors: "Not found"}
  end

  @impl true
  def handle_unprocessable_entity(conn) do
    %{errors: "Unprocessable entity"}
  end

  @impl true
  def respond_with_entity?(conn) do
    conn.method != "DELETE"
  end

  @impl true
  def handle_error(conn, error, failed_step) do
    Logger.error("conn failed at step #{failed_step} with error #{inspect error}")
    Plug.Conn.send_resp(conn, 500, "Internal server error")
  end
end