Rails 7 brings a host of new features and improvements, making it even easier to build robust and maintainable web applications. One of the powerful features available in Rails is the ability to create virtual (or computed/generated) columns in your database tables. In this blog post, we’ll explore how to create a virtual column in Rails 7 along with detailed explanations and examples.
What Are Virtual Columns?
Virtual columns are database columns that are not directly stored but computed based on expressions involving other columns. They can be particularly useful for derived data, such as concatenations, calculations, or transformations that should always be consistent with the source data.
Example Scenario
Let’s say we have a PersonalDocuments
table, and we want to add a full_name
column that stores a person’s full name and a virtual column full_name_length
that calculates the length of the full_name
.
Creating the Migration
To create the PersonalDocuments
table with the required columns, we will use the create_table
migration method. Here’s how you can do it:
Migration
1
2
3
4
5
6
7
8
9
10
class CreatePersonalDocuments < ActiveRecord::Migration[7.0]
def change
create_table :personal_documents do |t|
t.string :full_name
t.virtual :full_name_length, type: :integer, as: "length(full_name)", stored: true
t.timestamps
end
end
end
In this migration:
create_table :personal_documents
creates a new table namedpersonal_documents
.t.string :full_name
adds afull_name
column to the table.t.virtual :full_name_length, type: :integer, as: "length(full_name)", stored: true
adds a virtual columnfull_name_length
that calculates the length of thefull_name
column.
The stored: true
option ensures that the value of full_name_length
is calculated when the row is inserted or updated and stored in the database. This makes querying more efficient as the value doesn’t need to be recalculated each time it is accessed.
Updating the Model
In your PersonalDocument
model, no special configuration is needed for the virtual column. It will be available as a read-only attribute.
Model
1
2
3
class PersonalDocument < ApplicationRecord
# Any other model logic
end
Using the Virtual Column
You can now use the full_name_length
virtual column just like any other attribute. Here’s an example of how to create a record and access the virtual column:
Usage
1
2
personal_document = PersonalDocument.create(full_name: "John Doe")
puts personal_document.full_name_length # Outputs: 8
Important Considerations
- Stored vs. Virtual: The
stored: true
option makes the column a “stored generated” column, meaning its value is calculated when the row is inserted or updated and stored in the database. If you want it to be recalculated on the fly every time it is accessed, you can usestored: false
(though support for this varies by database).
Verifying the Setup
After running the migration, you can verify the columns with the following Rails console commands:
1
2
3
4
rails db:migrate
rails console
personal_document = PersonalDocument.create(full_name: "Jane Doe")
puts personal_document.full_name_length # Should output: 8
This setup ensures that whenever the full_name
is updated, the full_name_length
virtual column is automatically recalculated and stored.