lib/bbox/votes/vote.ex

defmodule Bbox.Votes.Vote do
  use Ecto.Schema
  import Ecto.Changeset

  alias Bbox.Candidates.Candidate
  alias Bbox.Voters.Voter

  @primary_key false
  @foreign_key_type :string
  @derive {Jason.Encoder, except: [:__meta__, :voter, :candidate, :signature]}
  schema "votes" do
    field(:index, :integer)
    field(:signature, :string)
    belongs_to(:voter, Voter, foreign_key: :voter_address, references: :address)
    belongs_to(:candidate, Candidate, foreign_key: :candidate_code, references: :code)
    field(:year, :integer)

    timestamps()
  end

  def changeset(vote, params \\ %{}) do
    vote
    |> cast(params, [:signature])
    |> validate_required([:signature])
    |> put_year()
  end

  def put_year(%Ecto.Changeset{valid?: true} = changeset) do
    year =
      DateTime.utc_now()
      |> Map.fetch!(:year)

    put_change(changeset, :year, year)
  end

  def put_year(changeset), do: changeset
end