dennismonsewicz
dennismonsewicz

Reputation: 25542

Phoenix plug to check for required query param

I have the following controller:

defmodule Campaigns.CampaignController do
  use Campaigns.Web, :controller

  alias Campaigns.Campaign
  alias Campaigns.ApiParams

  plug :ensure_account_id

  def index(conn, %{"account_id" => account_id}) do
    query = from c in Campaign, where: [account_id: ^account_id]
    render(conn, "index.json", campaigns: Repo.all(query))
  end

  def show(conn, %{"id" => id, "account_id" => account_id}) do
    query = from c in Campaign, where: [id: ^id, account_id: ^account_id]
    render(conn, "show.json", campaign: Repo.one(query))
  end

  defp ensure_account_id(conn, _) do
    cs = ApiParams.changeset(%ApiParams{}, conn.params)
    case cs do
      %{:params => %{"account_id" => account_id}, :valid? => true} ->
        conn
      _ ->
        conn
        |> put_status(400)
        |> render(conn, "400.json", "account_id is missing")
    end
  end
end

I am wanting to ensure that the account_id is present in the request made to each endpoint in this controller. The error in the console I am getting is

[error] #PID<0.403.0> running Campaigns.Endpoint terminated
Server: localhost:4000 (http)
Request: GET /api/campaigns/1
** (exit) an exception was raised:
    ** (FunctionClauseError) no function clause matching in Phoenix.Controller.render/4

But I have a render("400.json" method in my ErrorView.ex file.

Here is my ErrorView.ex file

defmodule Campaigns.ErrorView do
  use Campaigns.Web, :view

  def render("404.html", _assigns) do
    "Page not found"
  end

  def render("500.html", _assigns) do
    "Internal server error"
  end

  def render("400.json", %{"message" => error}) do
    %{error: error}
  end

  # In case no render clause matches or no
  # template is found, let's render it as 500
  def template_not_found(_template, assigns) do
    render "500.html", assigns
  end
end

Upvotes: 0

Views: 2230

Answers (1)

TheAnh
TheAnh

Reputation: 2813

defp ensure_account_id(conn, _) do
cs = ApiParams.changeset(%ApiParams{}, conn.params)
case cs do
  %{:params => %{"account_id" => account_id}, :valid? => true} ->
    conn
  _ ->
    conn
    |> put_status(400)
    |> render("400.json", message: "account_id is missing") # remove the `conn` here
end

end

Upvotes: 1

Related Questions