PostgreSQL’s citext
extension provides case-insensitive text fields, which are useful when you want to ensure uniqueness or perform comparisons without worrying about letter casing. In Ash, you can take advantage of citext
by using the :ci_string
type. Here’s how to set it up.
Add the citext
extension to your repository
AshPostgres allows you to manage PostgreSQL extensions through your repo module. To enable citext
, update your repo:
defmodule MyApp.Repo do
use AshPostgres.Repo,
otp_app: :my_app
@impl true
def installed_extensions do
# Add the citext extension here
["ash-functions", "citext"]
end
end
Update your resource to use :ci_string
In your resource module, change the attribute type to :ci_string
and mark it as a unique identity:
defmodule MyApp.Core.Vehicle do
use Ash.Resource,
domain: MyApp.Core,
data_layer: AshPostgres.DataLayer
postgres do
table "vehicles"
repo MyApp.Repo
end
attributes do
uuid_primary_key :id
attribute :name, :ci_string do
allow_nil? false
end
timestamps()
end
identities do
identity :unique_name, [:name], message: "Name must be unique"
end
end
Generate and apply the migrations
Finally, generate and run the migrations to apply the changes:
mix ash_postgres.generate_migrations unique_vehicle_name
mix ash_postgres.migrate
Now your name
field will use PostgreSQL's citext
type, ensuring case-insensitive uniqueness at the database level.
If this post was enjoyable or useful for you, please share it! If you have comments, questions, or feedback, you can email my personal email. To get new posts, subscribe use the RSS feed.