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