When working with Phoenix, the web framework built on Elixir, you’ll often find yourself defining schemas to map your database tables to Elixir structs. These schemas are powerful tools that help manage data interactions in a clean, structured way. But sometimes, you may need to work with fields that aren't stored in the database—this is where virtual fields come in.
In this article, we’ll explore what virtual fields are, why they are useful, and how to implement them in your Phoenix schemas.
What Are Virtual Fields?
A virtual field is a field that is part of your schema but is not persisted in your database. Unlike regular fields, virtual fields exist purely in the context of your application, often used for temporary data or operations that don’t require the field to be stored.
For example, you might use a virtual field to handle password confirmation during user registration or to store a derived value that doesn’t need to be saved.
Why Use Virtual Fields?
Virtual fields can be incredibly useful in various scenarios:
Temporary Data Storage: Sometimes, you need to store data temporarily during an operation, such as when validating form inputs or handling file uploads.
Derived Values: If you need to calculate a value based on other fields, a virtual field can be a good place to store this derived value without polluting your database.
Enhanced Security: For fields like password confirmations or tokens that should not be stored, virtual fields ensure that sensitive information isn’t accidentally saved in your database.
Clean Code: Using virtual fields keeps your code clean and easy to maintain, as you don’t need to create additional columns in your database for temporary or calculated data.
How to Define Virtual Fields in Phoenix
Defining a virtual field in a Phoenix schema is straightforward. You can define it just like any other field, but with the virtual: true
option.
Here’s an example:
defmodule MyApp.Accounts.User do
use Ecto.Schema
schema "users" do
field :email, :string
field :password_hash, :string
field :password, :string, virtual: true
field :password_confirmation, :string, virtual: true
timestamps()
end
end
In this example, password
and password_confirmation
are virtual fields. They will not be stored in the users
table in the database but can be used in your application logic.
Using Virtual Fields in Changesets
Virtual fields are often used in changesets for validation and transformations. Here’s how you might validate a user’s password and confirmation:
defmodule MyApp.Accounts.User do
use Ecto.Schema
import Ecto.Changeset
schema "users" do
field :email, :string
field :password_hash, :string
field :password, :string, virtual: true
field :password_confirmation, :string, virtual: true
timestamps()
end
def changeset(user, attrs) do
user
|> cast(attrs, [:email, :password, :password_confirmation])
|> validate_required([:email, :password, :password_confirmation])
|> validate_length(:password, min: 6)
|> validate_confirmation(:password)
|> hash_password()
end
defp hash_password(changeset) do
if password = get_change(changeset, :password) do
put_change(changeset, :password_hash, Bcrypt.hash_pwd_salt(password))
else
changeset
end
end
end
In this changeset, password
and password_confirmation
are cast from the input parameters, validated, and used to generate a password_hash
that is stored in the database. The virtual fields allow you to work with these values without persisting them.
Common Use Cases for Virtual Fields
Password Handling: As shown in the example above, virtual fields are often used to handle passwords securely by ensuring that plain text passwords are not stored in the database.
Token Management: Virtual fields can be used for managing temporary tokens, such as email verification tokens or password reset tokens.
Form Input Processing: When processing multi-step forms, virtual fields can temporarily store user inputs that are not yet ready to be saved in the database.
Computed Fields: For example, you might have a
full_name
virtual field that combinesfirst_name
andlast_name
fields.
Conclusion
Virtual fields in Phoenix schemas provide a powerful and flexible way to manage data that doesn’t need to be stored in your database. By using virtual fields, you can keep your schema clean, enhance security, and handle complex operations without unnecessary database changes.
Understanding when and how to use virtual fields will make your Phoenix applications more robust and easier to maintain. Whether you're handling sensitive data like passwords or working with derived values, virtual fields are an essential tool in your Phoenix development toolkit.
At ElixirMasters, we specialize in creating robust and scalable web applications using Phoenix and Elixir. If you're looking to build real-time applications, optimize your existing infrastructure, or integrate Elixir into your tech stack, we are here to help.
For more information about how we can assist your business with Elixir development, visit ElixirMasters or get in touch with us today. Our parent company, BetaMize, also offers a wide range of digital transformation services for businesses looking to leverage modern technology for growth.
Let’s build something great together!