mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-23 20:18:00 +01:00
Extract query validation callback step to custom validator
This commit is contained in:
parent
ade92481f8
commit
c89424d146
4 changed files with 77 additions and 24 deletions
|
@ -1,9 +1,10 @@
|
||||||
defmodule Philomena.Filters.Filter do
|
defmodule Philomena.Filters.Filter do
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
|
import PhilomenaQuery.Ecto.QueryValidator
|
||||||
|
|
||||||
alias Philomena.Schema.TagList
|
alias Philomena.Schema.TagList
|
||||||
alias Philomena.Schema.Search
|
alias Philomena.Images.Query
|
||||||
alias Philomena.Users.User
|
alias Philomena.Users.User
|
||||||
alias Philomena.Repo
|
alias Philomena.Repo
|
||||||
|
|
||||||
|
@ -48,8 +49,8 @@ defmodule Philomena.Filters.Filter do
|
||||||
|> validate_required([:name])
|
|> validate_required([:name])
|
||||||
|> validate_my_downvotes(:spoilered_complex_str)
|
|> validate_my_downvotes(:spoilered_complex_str)
|
||||||
|> validate_my_downvotes(:hidden_complex_str)
|
|> validate_my_downvotes(:hidden_complex_str)
|
||||||
|> Search.validate_search(:spoilered_complex_str, user)
|
|> validate_query(:spoilered_complex_str, &Query.compile(&1, user: user))
|
||||||
|> Search.validate_search(:hidden_complex_str, user)
|
|> validate_query(:hidden_complex_str, &Query.compile(&1, user: user))
|
||||||
|> unsafe_validate_unique([:user_id, :name], Repo)
|
|> unsafe_validate_unique([:user_id, :name], Repo)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
defmodule Philomena.Schema.Search do
|
|
||||||
alias Philomena.Images.Query
|
|
||||||
alias PhilomenaQuery.Parse.String
|
|
||||||
import Ecto.Changeset
|
|
||||||
|
|
||||||
def validate_search(changeset, field, user, watched \\ false) do
|
|
||||||
query = changeset |> get_field(field) |> String.normalize()
|
|
||||||
output = Query.compile(query, user: user, watch: watched)
|
|
||||||
|
|
||||||
case output do
|
|
||||||
{:ok, _} ->
|
|
||||||
changeset
|
|
||||||
|
|
||||||
_ ->
|
|
||||||
add_error(changeset, field, "is invalid")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -4,10 +4,11 @@ defmodule Philomena.Users.User do
|
||||||
|
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
|
import PhilomenaQuery.Ecto.QueryValidator
|
||||||
|
|
||||||
alias Philomena.Schema.TagList
|
alias Philomena.Schema.TagList
|
||||||
alias Philomena.Schema.Search
|
|
||||||
|
|
||||||
|
alias Philomena.Images.Query
|
||||||
alias Philomena.Filters.Filter
|
alias Philomena.Filters.Filter
|
||||||
alias Philomena.ArtistLinks.ArtistLink
|
alias Philomena.ArtistLinks.ArtistLink
|
||||||
alias Philomena.Badges
|
alias Philomena.Badges
|
||||||
|
@ -354,8 +355,8 @@ defmodule Philomena.Users.User do
|
||||||
|> validate_inclusion(:images_per_page, 1..50)
|
|> validate_inclusion(:images_per_page, 1..50)
|
||||||
|> validate_inclusion(:comments_per_page, 1..100)
|
|> validate_inclusion(:comments_per_page, 1..100)
|
||||||
|> validate_inclusion(:scale_large_images, ["false", "partscaled", "true"])
|
|> validate_inclusion(:scale_large_images, ["false", "partscaled", "true"])
|
||||||
|> Search.validate_search(:watched_images_query_str, user, true)
|
|> validate_query(:watched_images_query_str, &Query.compile(&1, user: user, watch: true))
|
||||||
|> Search.validate_search(:watched_images_exclude_str, user, true)
|
|> validate_query(:watched_images_exclude_str, &Query.compile(&1, user: user, watch: true))
|
||||||
end
|
end
|
||||||
|
|
||||||
def description_changeset(user, attrs) do
|
def description_changeset(user, attrs) do
|
||||||
|
|
69
lib/philomena_query/ecto/query_validator.ex
Normal file
69
lib/philomena_query/ecto/query_validator.ex
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
defmodule PhilomenaQuery.Ecto.QueryValidator do
|
||||||
|
@moduledoc """
|
||||||
|
Query string validation for Ecto.
|
||||||
|
|
||||||
|
It enables the following usage pattern by taking a fn of the compiler:
|
||||||
|
|
||||||
|
defmodule Filter do
|
||||||
|
import PhilomenaQuery.Ecto.QueryValidator
|
||||||
|
|
||||||
|
# ...
|
||||||
|
|
||||||
|
def changeset(filter, attrs, user) do
|
||||||
|
filter
|
||||||
|
|> cast(attrs, [:complex])
|
||||||
|
|> validate_required([:complex])
|
||||||
|
|> validate_query([:complex], with: &Query.compile(&1, user: user))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import Ecto.Changeset
|
||||||
|
alias PhilomenaQuery.Parse.String
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Validates a query string using the provided attribute(s) and compiler.
|
||||||
|
|
||||||
|
Returns the changeset as-is, or with an `"is invalid"` error added to validated field.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
# With single attribute
|
||||||
|
filter
|
||||||
|
|> cast(attrs, [:complex])
|
||||||
|
|> validate_query(:complex, &Query.compile(&1, user: user))
|
||||||
|
|
||||||
|
# With list of attributes
|
||||||
|
filter
|
||||||
|
|> cast(attrs, [:spoilered_complex, :hidden_complex])
|
||||||
|
|> validate_query([:spoilered_complex, :hidden_complex], &Query.compile(&1, user: user))
|
||||||
|
|
||||||
|
"""
|
||||||
|
def validate_query(changeset, attr_or_attr_list, callback)
|
||||||
|
|
||||||
|
def validate_query(changeset, attr_list, callback) when is_list(attr_list) do
|
||||||
|
Enum.reduce(attr_list, changeset, fn attr, changeset ->
|
||||||
|
validate_query(changeset, attr, callback)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
def validate_query(changeset, attr, callback) do
|
||||||
|
if changed?(changeset, attr) do
|
||||||
|
validate_assuming_changed(changeset, attr, callback)
|
||||||
|
else
|
||||||
|
changeset
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp validate_assuming_changed(changeset, attr, callback) do
|
||||||
|
with value when is_binary(value) <- fetch_change!(changeset, attr) || "",
|
||||||
|
value <- String.normalize(value),
|
||||||
|
{:ok, _} <- callback.(value) do
|
||||||
|
changeset
|
||||||
|
else
|
||||||
|
_ ->
|
||||||
|
add_error(changeset, attr, "is invalid")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue