+ def blocked_ap_ids(user) do
+ user
+ |> assoc(:blocked_users)
+ |> select([u], u.ap_id)
+ |> Repo.all()
+ end
+
+ defp related_ap_ids_sql(join_table, source_column, target_column) do
+ "(SELECT array_agg(u.ap_id) FROM users as u " <>
+ "INNER JOIN #{join_table} AS join_table " <>
+ "ON join_table.#{source_column} = $1 " <>
+ "WHERE u.id = join_table.#{target_column})"
+ end
+
+ @related_ap_ids_sql_params %{
+ blocked_users: ["user_blocks", "blocker_id", "blockee_id"],
+ muted_users: ["user_mutes", "muter_id", "mutee_id"]
+ }
+
+ def related_ap_ids(user, relations) when is_list(relations) do
+ query =
+ relations
+ |> Enum.map(fn r -> @related_ap_ids_sql_params[r] end)
+ |> Enum.filter(& &1)
+ |> Enum.map(fn [join_table, source_column, target_column] ->
+ related_ap_ids_sql(join_table, source_column, target_column)
+ end)
+ |> Enum.join(", ")
+
+ with {:ok, %{rows: [ap_ids_arrays]}} <-
+ Repo.query("SELECT #{query}", [FlakeId.from_string(user.id)]) do
+ ap_ids_arrays = Enum.map(ap_ids_arrays, &(&1 || []))
+ {:ok, ap_ids_arrays}
+ end
+ end
+