defmodule GitGud.Profiles.Pin do
use Ecto.Schema
import Ecto.Changeset
alias GitGud.Accounts.User
alias GitGud.Organizations.Organization
alias GitGud.Repositories.Repository
schema "pinned_repositories" do
field :position, :integer, default: 0
belongs_to :owner, User
belongs_to :organization, Organization
belongs_to :repository, Repository
timestamps(type: :utc_datetime)
end
def changeset(pin, attrs) do
pin
|> cast(attrs, [:owner_id, :organization_id, :repository_id, :position])
|> validate_required([:repository_id])
|> validate_owner_xor_org()
|> unique_constraint([:owner_id, :repository_id],
name: :pinned_repositories_owner_id_repository_id_index
)
|> unique_constraint([:organization_id, :repository_id],
name: :pinned_repositories_organization_id_repository_id_index
)
|> foreign_key_constraint(:repository_id)
end
defp validate_owner_xor_org(cs) do
owner = get_field(cs, :owner_id)
org = get_field(cs, :organization_id)
cond do
is_integer(owner) and is_integer(org) ->
add_error(cs, :owner_id, "pin can't be owned by both a user and an organization")
is_nil(owner) and is_nil(org) ->
add_error(cs, :owner_id, "pin must have a user or organization owner")
true ->
cs
end
end
end
1.3 KiB · text
5af55d9