Refactoring of Events context

This commit is contained in:
miffigriffy
2019-09-13 01:01:17 +02:00
parent e4a446003d
commit e358dcce77
19 changed files with 528 additions and 353 deletions

View File

@@ -1,73 +1,46 @@
import EctoEnum
defenum(Mobilizon.Events.ParticipantRoleEnum, :participant_role_type, [
:not_approved,
:participant,
:moderator,
:administrator,
:creator
])
defmodule Mobilizon.Events.Participant do
@moduledoc """
Represents a participant, an actor participating to an event
Represents a participant, an actor participating to an event.
"""
use Ecto.Schema
import Ecto.Changeset
alias Mobilizon.Events.{Participant, Event}
alias Mobilizon.Actors.Actor
alias Mobilizon.Config
alias Mobilizon.Events
alias Mobilizon.Events.{Event, Participant, ParticipantRole}
@type t :: %__MODULE__{
role: ParticipantRole.t(),
url: String.t(),
event: Event.t(),
actor: Actor.t()
}
@required_attrs [:url, :role, :event_id, :actor_id]
@attrs @required_attrs
@primary_key {:id, :binary_id, autogenerate: true}
schema "participants" do
field(:role, Mobilizon.Events.ParticipantRoleEnum, default: :participant)
field(:role, ParticipantRole, default: :participant)
field(:url, :string)
belongs_to(:event, Event, primary_key: true)
belongs_to(:actor, Actor, primary_key: true)
timestamps()
end
@doc false
def changeset(%Participant{} = participant, attrs) do
participant
|> Ecto.Changeset.cast(attrs, [:url, :role, :event_id, :actor_id])
|> generate_url()
|> validate_required([:url, :role, :event_id, :actor_id])
end
# If there's a blank URL that's because we're doing the first insert
defp generate_url(%Ecto.Changeset{data: %Participant{url: nil}} = changeset) do
case fetch_change(changeset, :url) do
{:ok, _url} -> changeset
:error -> do_generate_url(changeset)
end
end
# Most time just go with the given URL
defp generate_url(%Ecto.Changeset{} = changeset), do: changeset
defp do_generate_url(%Ecto.Changeset{} = changeset) do
uuid = Ecto.UUID.generate()
changeset
|> put_change(
:url,
"#{MobilizonWeb.Endpoint.url()}/join/event/#{uuid}"
)
|> put_change(
:id,
uuid
)
end
@doc """
We check that the actor asking to leave the event is not it's only organizer
We check that the actor asking to leave the event is not it's only organizer.
We start by fetching the list of organizers and if there's only one of them
and that it's the actor requesting leaving the event we return true
and that it's the actor requesting leaving the event we return true.
"""
@spec check_that_participant_is_not_only_organizer(integer(), integer()) :: boolean()
def check_that_participant_is_not_only_organizer(event_id, actor_id) do
case Mobilizon.Events.list_organizers_participants_for_event(event_id) do
@spec is_not_only_organizer(integer | String.t(), integer | String.t()) :: boolean
def is_not_only_organizer(event_id, actor_id) do
case Events.list_organizers_participants_for_event(event_id) do
[%Participant{actor: %Actor{id: participant_actor_id}}] ->
participant_actor_id == actor_id
@@ -75,4 +48,39 @@ defmodule Mobilizon.Events.Participant do
false
end
end
@doc false
@spec changeset(t, map) :: Ecto.Changeset.t()
def changeset(%Participant{} = participant, attrs) do
participant
|> cast(attrs, @attrs)
|> ensure_url()
|> validate_required(@required_attrs)
end
# If there's a blank URL that's because we're doing the first insert
@spec ensure_url(Ecto.Changeset.t()) :: Ecto.Changeset.t()
defp ensure_url(%Ecto.Changeset{data: %Participant{url: nil}} = changeset) do
case fetch_change(changeset, :url) do
{:ok, _url} ->
changeset
:error ->
update_url(changeset)
end
end
defp ensure_url(%Ecto.Changeset{} = changeset), do: changeset
defp update_url(%Ecto.Changeset{} = changeset) do
uuid = Ecto.UUID.generate()
url = generate_url(uuid)
changeset
|> put_change(:id, uuid)
|> put_change(:url, url)
end
@spec generate_url(String.t()) :: String.t()
defp generate_url(uuid), do: "#{Config.instance_hostname()}/join/event/#{uuid}"
end