defmodule Diffuser.Generator.PromptRequest do use Diffuser.Schema use Waffle.Ecto.Schema import Ecto.Changeset import Ecto.Query alias Diffuser.Generator.PromptRequestResult alias Diffuser.Accounts.{User, Vote} @valid_codes Application.get_env(:diffuser, :valid_codes, []) schema "prompt_requests" do field :prompt, :string field :status, :string, default: "queued" field :steps, :integer, default: 32 field :completed_steps, :integer, default: 0 field :guidance_scale, :float, default: 7.5 field :began_at, :utc_datetime field :ended_at, :utc_datetime field :code, :string has_many :images, PromptRequestResult, on_delete: :delete_all has_many :votes, Vote, on_delete: :delete_all belongs_to :user, User timestamps() end @doc false def changeset(prompt_request, attrs) do prompt_request |> cast(attrs, [ :prompt, :status, :steps, :guidance_scale, :completed_steps, :began_at, :ended_at, :code ]) |> validate_number(:steps, less_than_or_equal_to: 60) |> validate_code() |> validate_required([:prompt]) end defp validate_code(changeset) do validate_change(changeset, :code, fn :code, code -> cond do @valid_codes |> Enum.any?(fn {_name, valid_code} -> valid_code == code end) -> [] true -> [code: "Code is invalid."] end end) end def search_by_prompt_or_user(query, nil), do: query def search_by_prompt_or_user(query, search_query) do from p in query, left_join: u in User, on: u.id == p.user_id, where: ilike(p.prompt, ^"%#{search_query}%") end def order_by(query, nil) do from p in query, order_by: [desc: p.inserted_at] end def order_by(query, "desc") do from p in query, join: v in Vote, on: v.prompt_request_id == p.id, group_by: p.id, order_by: [desc: count(v.id)] end def order_by(query, "asc") do from p in query, left_join: v in Vote, on: v.prompt_request_id == p.id, group_by: p.id, order_by: [asc: count(v.id)] end end