more complete fix for commission and gallery pagination error

This commit is contained in:
byte[] 2020-08-01 12:42:29 -04:00
parent d303d02d2c
commit 5532ea4dec
4 changed files with 42 additions and 8 deletions

View file

@ -5,6 +5,7 @@ defmodule PhilomenaWeb.CommissionController do
alias Philomena.Repo
import Ecto.Query
plug PhilomenaWeb.MapParameterPlug, [param: "commission"] when action in [:index]
plug :preload_commission
def index(conn, params) do
@ -12,10 +13,6 @@ defmodule PhilomenaWeb.CommissionController do
commission_search(params["commission"])
|> Repo.paginate(conn.assigns.scrivener)
# Scrub parameters to avoid form error...
params = Map.put(conn.params, "commission", permit_map(conn.params["commission"]))
conn = Map.put(conn, :params, params)
render(conn, "index.html",
title: "Commissions",
commissions: commissions,
@ -88,9 +85,6 @@ defmodule PhilomenaWeb.CommissionController do
defp presence(object),
do: object
defp permit_map(x) when is_map(x), do: x
defp permit_map(_), do: nil
defp to_f(input) do
case Float.parse(to_string(input)) do
{float, _rest} -> float

View file

@ -10,6 +10,7 @@ defmodule PhilomenaWeb.GalleryController do
import Ecto.Query
plug PhilomenaWeb.FilterBannedUsersPlug when action in [:new, :create, :edit, :update, :delete]
plug PhilomenaWeb.MapParameterPlug, [param: "gallery"] when action in [:index]
plug :load_and_authorize_resource,
model: Gallery,

View file

@ -0,0 +1,39 @@
defmodule PhilomenaWeb.MapParameterPlug do
# A bunch of crappy behaviors all interacting to create a
# symphony of failure:
#
# 1.) Router helpers do not strip nil query parameters.
# iex> Routes.gallery_path(conn, :index, gallery: nil)
# "/galleries?gallery="
#
# 2.) Pagination always sets the parameter in the route in order
# to preserve the query across multiple pages
#
# 3.) When received by the router, an empty param is treated as
# an empty string instead of nil
#
# 4.) Phoenix.HTML.Form.form_for/2 raises an error if you try to
# use it on a conn object which is a string instead of a map
# (or nil)
@spec init(Keyword.t()) :: Keyword.t()
def init(opts) do
opts
end
@spec call(Plug.Conn.t(), Keyword.t()) :: Plug.Conn.t()
def call(conn, opts) do
param = Keyword.fetch!(opts, :param)
value = conn.params[param]
cond do
is_map(value) ->
conn
true ->
params = Map.delete(conn.params, param)
Map.put(conn, :params, params)
end
end
end