---
title: Creating static data for your Rails application
teaser: How to create flexible and maintainable static data for your Rails application
  using static_association.
tags: ruby on rails,development,web
author: Trésor Bireke
published_on: 2024-11-22
---

#### Introduction

Creating a new database table is great, but sometimes, you have a known set of values for which creating a new table feels like an overhead.
That's when static associations come into place.

#### What is `static_association` ?

Static association is a gem that adds basic ActiveRecord-like associations to static data in your Rails application. Instead of storing reference data in a database table, `static_association` allows you to define this data directly in your models. This can make querying for static data faster since it avoids database lookups.

#### Installation and Usage

Installing this gem is pretty straightforward.

Add `gem "static_association"` to your `Gemfile`, then run `bundle` and you should be ready to go.

Next, we create the static association class like this:

```ruby
class RepaymentFrequency

  include StaticAssociation

  attr_accessor :name, :months_per_repayment_period, :selectable

  record id: 0 do |r|
    r.name = "Annually"
    r.months_per_repayment_period = 12
    r.selectable = true
  end

  record id: 1 do |r|
    r.name = "Quarterly"
    r.months_per_repayment_period = 3
    r.selectable = true
  end

  record id: 2 do |r|
    r.name = "Monthly"
    r.months_per_repayment_period = 1
    r.selectable = true
  end

  record id: 3 do |r|
    r.name = "Interest Only - Single Repayment on Maturity"
    r.months_per_repayment_period = 0
    r.selectable = true
  end
end
```

Currently, `static_association` only supports `belongs_to` associations. We can associate the static model with any active record model that has a foreign key of `repayment_frequency_id`.

```ruby
class Loan < ActiveRecord::Base
  extend StaticAssociation::AssociationHelpers

  belongs_to_static :repayment_frequency
end
```

Here, the `loans` table should have `repayment_frequency_id` as a foreign key.
Right now, `static_association` has a limited set of methods available; in the above example, the `RepaymentFrequency` class will gain `.all`, `.find`, `.find_by_id`, and `.where` methods.

You can look at the [Github Repo](https://github.com/thoughtbot/static_association) to check if more methods have been added.

#### `static_association` vs `enum`

Both `static_association` and `enum` in Rails can be used for handling limited sets of values, but they differ in how they store and retrieve those values. Here’s a quick comparison to help you decide which one fits better for your use case:

##### **1. `enum` in Rails**

- **Pros**:
  - **Built-in Methods**: Rails provides helper methods for querying, setting, and manipulating enums (e.g., `status.active!`, `User.where(status: :active)`).
  - **Simplicity**: Enums are part of the Rails core, so they require no additional gems or configuration.
  - **Scope & Validation**: Automatically creates scopes and validations (e.g., `User.active`).
- **Cons**:
  - **Harder to Maintain**: Changing or removing an enum value can be tricky. Since values are stored as integers, removing or reordering enum keys can break existing data.
  - **Lack of Flexibility**: Additional metadata or attributes cannot be easily associated with the enum values.

##### **2. `static_association` Gem**

- **Pros**:
  - **Flexibility**: Since values are stored in a separate table, you can easily associate additional metadata or attributes (e.g., descriptions, codes) with each value.
  - **Easier to Maintain**: Adding or changing values doesn’t require a migration, and you don’t run into issues with removing or renaming values as you do with enums.
  - **Querying Power**: Since it’s a true association, you can easily join on the lookup table, query it, and use ActiveRecord’s association methods.
  - **Readable**: Rather than storing an integer, your database stores a meaningful reference (foreign key), which can make it easier to work with directly at the database level.
- **Cons**:
  - **Overhead**: Adds additional complexity with the need to maintain a lookup table and relationships.
  - **Performance**: Slightly more overhead with joins compared to `enum` as it requires querying a related table.

Using the example from the usage section, if you wanted to prevent a repayment_frequency from being selected, you'd just have to update the `selectable` attribute to `false`.
Using static association, we can add other attributes like a different interest rate for each repayment frequency without breaking the existing code or needing much refactoring.

``` ruby
  record id: 1 do |r|
    r.name = "Quarterly"
    r.months_per_repayment_period = 3
    r.selectable = true
    r.interest_rate = 2.5
  end
```

Hopefully, that comparison makes it easier to decide which one fits your use case.
