I have a schema named UserProfile. That schema has a field :birth_date
which is a date. That schema has also a field named :zodiac
which is calculated by :birth_date
.
schema "user_profiles" do
# Other fields
field :birth_date, Timex.Ecto.Date
field :zodiac, :string
To keep things as up to date and consistent as possible I have set a index on expression in the database to calculate the :zodiac
value. So the :zodiac
is calculated on the database itself, not in elixir code.
execute("""
CREATE OR REPLACE FUNCTION zodiac(user_profiles)
RETURNS text AS $$
SELECT
CASE
WHEN (date_part('month', $1.birth_date) = 3 AND date_part('day', $1.birth_date) >= 21) OR (date_part('month', $1.birth_date) = 4 AND date_part('day', $1.birth_date) <= 19) THEN 'ari'
--- ... More conditions
END
$$ STABLE LANGUAGE SQL;
""")
execute("CREATE INDEX zodiac_index ON user_profiles(zodiac(user_profiles));")
But now when I create a user_profile
the returned struct still has the :zodiac
set to nil
.
test "list_users/1 returns all users" do
users = for _ <- 1..1 do
fixture(:user)
end
assert Accounts.list_users() |> Repo.preload(:user_profile) == users
end
fails with
left: [%Mysite.Accounts.User{
#...
user_profile: %Mysite.Accounts.UserProfile{
#...
zodiac: "tau"}}]
right: [%Mysite.Accounts.User{
#...,
user_profile: %Mysite.Accounts.UserProfile{
# ...,
zodiac: nil}}]
I tried setting
field :zodiac, :string, read_after_writes: true
but it complains
** (Postgrex.Error) ERROR 42703 (undefined_column): column "zodiac" does not exist
So how can I have the field available in the struct right after creation?