[#3213] Partially addressed code review points.
[akkoma] / lib / pleroma / hashtag.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Hashtag do
6 use Ecto.Schema
7
8 import Ecto.Changeset
9
10 alias Pleroma.Hashtag
11 alias Pleroma.Repo
12
13 schema "hashtags" do
14 field(:name, :string)
15
16 many_to_many(:objects, Pleroma.Object, join_through: "hashtags_objects", on_replace: :delete)
17
18 timestamps()
19 end
20
21 def get_by_name(name) do
22 Repo.get_by(Hashtag, name: name)
23 end
24
25 def get_or_create_by_name(name) when is_bitstring(name) do
26 with %Hashtag{} = hashtag <- get_by_name(name) do
27 {:ok, hashtag}
28 else
29 _ ->
30 %Hashtag{}
31 |> changeset(%{name: name})
32 |> Repo.insert()
33 end
34 end
35
36 def get_or_create_by_names(names) when is_list(names) do
37 Enum.reduce_while(names, {:ok, []}, fn name, {:ok, list} ->
38 case get_or_create_by_name(name) do
39 {:ok, %Hashtag{} = hashtag} ->
40 {:cont, {:ok, list ++ [hashtag]}}
41
42 error ->
43 {:halt, error}
44 end
45 end)
46 end
47
48 def changeset(%Hashtag{} = struct, params) do
49 struct
50 |> cast(params, [:name])
51 |> update_change(:name, &String.downcase/1)
52 |> validate_required([:name])
53 |> unique_constraint(:name)
54 end
55 end