DEV Community

Yashika Vijayvargiya
Yashika Vijayvargiya

Posted on Originally published at Medium on

Rails 8.1: Using only_columns to Control Which Database Columns Active Record Uses

When working with legacy databases or large Rails applications, a model may have more database columns than the application actually needs.

Some columns might belong to an older feature, a third-party integration, or a database structure shared by multiple applications.

Traditionally, Rails developers could use ignored_columns to tell Active Record which columns to ignore. With Rails 8.1, only_columns provides the opposite approach: explicitly list the columns a model should use.

Let’s understand how it works, how to test it in the Rails console, and when it can be useful.

1. What Is only_columns in Rails 8.1?

ActiveRecord::Base.only_columns allows you to specify the database columns that a model should recognize and use.

Instead of listing the columns you want to ignore, you list the columns you want Active Record to use.

Consider a users table with these columns:

id
name
email
phone
address
legacy_reference
external_customer_id
created_at
updated_at
Enter fullscreen mode Exit fullscreen mode

Suppose your application only needs:

  • id
  • name
  • email
  • created_at
  • updated_at

You can explicitly define that list in your model.

2. How to Use only_columns

Let’s use a User model as an example.

app/models/user.rb

class User < ApplicationRecord
  self.only_columns = %w[
    id
    name
    email
    created_at
    updated_at
  ]
end
Enter fullscreen mode Exit fullscreen mode

Now, Active Record uses the configured column list when defining model attributes and constructing SQL queries.

The database schema itself remains unchanged. The phone, address, legacy_reference, and external_customer_id columns still exist in the database.

The difference is that this model is configured to work with an explicitly defined subset of those columns.

3. Test It in the Rails Console

One of the easiest ways to understand this feature is to inspect the model directly.

Start the Rails console:

bin/rails console
Enter fullscreen mode Exit fullscreen mode

Check the configured columns:

User.only_columns
Enter fullscreen mode Exit fullscreen mode

Expected output:

["id", "name", "email", "created_at", "updated_at"]
Enter fullscreen mode Exit fullscreen mode

You can also inspect the model’s recognized column names:

User.column_names
Enter fullscreen mode Exit fullscreen mode

The result reflects the columns Active Record recognizes for this model, subject to the configured column list.

To inspect the attributes of a new record:

user = User.new

user.attributes.keys
Enter fullscreen mode Exit fullscreen mode

The attribute list should reflect the configured columns rather than every column in the database table.

This is useful when debugging a model in the Rails console: you can check which columns the model is configured to use without changing the underlying database schema.

4. Why Is This Useful?

A. Working with legacy databases

Imagine you’re maintaining an application that has been running for several years.

Its database contains columns left behind by older features:

users
-----
id
name
email
old_subscription_id
legacy_status
deprecated_reference
created_at
updated_at
Enter fullscreen mode Exit fullscreen mode

Your current application only needs the user’s basic information.

With only_columns, you can explicitly declare the columns that the model should use.

This makes the intended model schema easier to understand and can reduce accidental dependencies on legacy columns.

B. Working with shared database schemas

Some applications share a database with another service or application.

For example, your Rails application might use a customers table that also contains columns maintained by an external integration.

You may not want your application model to depend on every column in that shared table.

An explicit column list helps document the subset that your application expects to use.

Remember, this does not prevent other applications or direct SQL queries from accessing the remaining database columns.

C. Making schema changes safer

Database changes often require careful coordination between deployments.

Suppose you’re planning to remove an obsolete column.

Rather than immediately removing the column from the database, you can first update the application so its model no longer depends on it.

A possible rollout is:

  1. Identify the columns the application actually needs.
  2. Configure only_columns to list those columns.
  3. Deploy the application and verify that it no longer depends on the obsolete column.
  4. Check other applications, background jobs, reports, and database queries for dependencies.
  5. Remove the obsolete column in a subsequent deployment when it is safe to do so.

This approach can make a schema migration easier to coordinate, especially when multiple application versions or services share a database.

However, only_columns does not automatically make a migration safe. You still need to verify that no other code depends on the column.

5. How Is only_columns Different from ignored_columns?

Rails already provides ignored_columns, so why introduce another option?

The difference is how you express your intention.

Using ignored_columns

class User < ApplicationRecord
  self.ignored_columns = %w[
    legacy_reference
    deprecated_reference
  ]
end
Enter fullscreen mode Exit fullscreen mode

This tells Active Record to ignore the listed columns.

It’s convenient when most columns remain relevant and only a few need to be excluded.

Using only_columns

class User < ApplicationRecord
  self.only_columns = %w[
    id
    name
    email
    created_at
    updated_at
  ]
end
Enter fullscreen mode Exit fullscreen mode

This explicitly lists the columns the model should use.

It’s convenient when you want to define a known subset rather than maintain a list of columns to exclude.

Feature

ignored_columns

only_columns

Approach

List columns to ignore

List columns to use

Best suited for

Excluding a small number of columns

Explicitly defining the model’s column set

Database schema

Unchanged

Unchanged

Can be combined with the other option?

No; use one approach per model

No; use one approach per model

Choose the approach that best communicates your application’s intent.

6. Is only_columns a Security Feature?

No. This distinction is important.

Although only_columns restricts the columns Active Record uses for a model, it should not be treated as a security or authorization mechanism.

For example, suppose your users table contains:

id
name
email
admin
password_digest
Enter fullscreen mode Exit fullscreen mode

Configuring a model to use only id, name, and email does not replace proper authorization, access control, or protection of sensitive information.

You should still implement appropriate authorization policies, validate permitted input, and protect sensitive attributes.

Use only_columns to control the model's expected database columns, not to enforce who can access data.

7. Things to Keep in Mind

Before adopting only_columns, consider the following:

  • Associations: Verify that the columns needed for association loading and joins are included.
  • Primary keys: Include the primary key or all required composite primary key columns.
  • Timestamps: Include created_at and updated_at if the model relies on them.
  • Background jobs and callbacks: Check whether callbacks or other application code depend on excluded attributes.
  • Schema changes: Confirm that other applications and queries no longer depend on a column before removing it from the database.
  • Rails version: Use a patched Rails release. Rails 8.1.4 includes a fix ensuring that only_columns is respected when constructing the SELECT clause. Earlier Rails 8.1 versions may not handle this correctly in all queries.

Also, test the behavior with your actual model and associations before applying it to production.

Conclusion

Rails 8.1’s only_columns provides an explicit way to tell Active Record which database columns a model should use.

It can be useful when working with legacy tables, shared schemas, and staged database changes.

The main takeaway is simple:

ignored_columns tells Rails what to leave out. only_columns tells Rails what to work with.

If you maintain Rails applications with evolving database schemas, this is a feature worth understanding and testing.

For more details, see the Rails 8.1 Release Notes and the Active Record ModelSchema API.

Top comments (0)