82 lines
2.5 KiB
Elixir
82 lines
2.5 KiB
Elixir
defmodule Rsh26pool.Voting.Room do
|
|
@moduledoc """
|
|
A voting room. Identified publicly by a short `room_number` used in URLs.
|
|
"""
|
|
use Ecto.Schema
|
|
import Ecto.Changeset
|
|
|
|
alias Rsh26pool.Voting.{Idea, Participant}
|
|
|
|
schema "rooms" do
|
|
field :room_number, :string
|
|
field :name, :string
|
|
field :votes_per_user, :integer, default: 3
|
|
field :status, :string, default: "open"
|
|
field :grouping_mode, :boolean, default: false
|
|
field :leader_threshold, :integer, default: 2
|
|
field :closes_at, :utc_datetime
|
|
field :grouped_at, :utc_datetime
|
|
|
|
# Virtual field backing the `datetime-local` input (wall-clock JST).
|
|
field :closes_at_local, :string, virtual: true
|
|
|
|
has_many :participants, Participant
|
|
has_many :ideas, Idea
|
|
|
|
timestamps(type: :utc_datetime)
|
|
end
|
|
|
|
@doc "Changeset used when the owner creates a new room."
|
|
def create_changeset(room, attrs) do
|
|
room
|
|
|> cast(attrs, [
|
|
:name,
|
|
:votes_per_user,
|
|
:grouping_mode,
|
|
:leader_threshold,
|
|
:closes_at_local
|
|
])
|
|
|> validate_required([:name, :votes_per_user], message: "入力してください")
|
|
|> validate_length(:name, max: 80, message: "80文字以内で入力してください")
|
|
|> validate_number(:votes_per_user,
|
|
greater_than_or_equal_to: 1,
|
|
less_than_or_equal_to: 50,
|
|
message: "1〜50の数値を入力してください"
|
|
)
|
|
|> validate_number(:leader_threshold,
|
|
greater_than_or_equal_to: 1,
|
|
less_than_or_equal_to: 50,
|
|
message: "1〜50の数値を入力してください"
|
|
)
|
|
|> put_closes_at()
|
|
end
|
|
|
|
@doc "Changeset for owner-editable settings on the manage page."
|
|
def settings_changeset(room, attrs) do
|
|
room
|
|
|> cast(attrs, [:name])
|
|
|> validate_required([:name], message: "入力してください")
|
|
|> validate_length(:name, max: 80, message: "80文字以内で入力してください")
|
|
end
|
|
|
|
defp put_closes_at(changeset) do
|
|
case get_field(changeset, :closes_at_local) do
|
|
blank when blank in [nil, ""] ->
|
|
put_change(changeset, :closes_at, nil)
|
|
|
|
value ->
|
|
case Rsh26pool.JST.parse_local(value) do
|
|
{:ok, dt} ->
|
|
if DateTime.compare(dt, DateTime.utc_now()) == :gt do
|
|
put_change(changeset, :closes_at, dt)
|
|
else
|
|
add_error(changeset, :closes_at_local, "未来の日時を指定してください")
|
|
end
|
|
|
|
:error ->
|
|
add_error(changeset, :closes_at_local, "日時の形式が正しくありません")
|
|
end
|
|
end
|
|
end
|
|
end
|