news

Don’t build! Buy a complete rails SaaS app.

Learn more

Add user settings to your Rails SaaS app

At some point in your Rails SaaS app’s life, you need to add some settings to your app. These settings can be global like loading text labels (if you don’t use I18n) or settings for any model (team or user) within your app, like timezone settings, date/time notation and language.

Other common use cases for settings like these can currency formatting, subscribed plan features or other domain specific settings.

While there are plenty of wonderful OSS options out there, I find this kind of feature not worth for to rely on a third party. It’s fairly straightforward and you can more easily tweak it to fit your exact needs.

Let’s add those settings

Our settings will be based off a polymorphic model called settings. It will contain a jsonb value to store the actual setting values and by using a polymorphic association, it can be scoped as easily to an User object as to a Team object.

First create a Setting model: rails g model Setting target:references{polymorphic} object value:jsonb. This will create a model for you and its migration. “Target” is the association that owns the settings, eg. an User or a Team. “Object” is the scope, which could be “general”, “features” or something domain-specific. Next we need to add some changes to the migration.

create_table :settings do |t|
  …      
  t.string :object, null: false
  t.jsonb :value, null: false, default: {}
  …
end

We add both “null: false” to “value” and “object” and set a default off “{}” to value.

Next we need to decide what kind of settings we want to save. Let’s go with general settings. Create a new file, in a new folder, called “settings”: “app/models/settings/general.rb”. This file will inherit from “app/models/setting.rb”.

class Settings::General < Setting
  default_scope -> { find_by(object: 'general') }

  store_accessor :value, :timezone, :default_currency, :theme
  validates_inclusion_of :default_currency, in: %w( eur usd gbp )	
  validates_inclusion_of :theme, in: %w( dark light )
  # …
end

First we set a default scope that will “link” this model to the right records in your database. The store_accessor makes working with jsonb columns a fair bit easier. Here we allow to add general settings for the “timezone”, “default_currency”, and “theme”. But, depending on your app, you can choose whatever settings you need here. And finally we add some validation to be sure the right values are persisted into the database.

Use these settings within your app

You can now read and write these settings as you would like any other model. Assuming you have a current user object: Settings::General.find_by(target: current_user).default_currency. Or saving a value: Settings::General.find_by(target: current_user).update default_currency: 'eur'.

And that’s it. A really versatile, basic and simple to add settings for your Rails SaaS app.

A Rails SaaS starter kit to build successful products