I blog about Ruby on Rails, coding, and servers

Quick & Easy User Preferences in Rails

Reading time 4 minutes

My first RubyMotion application is rapidly nearing completion. As it involves user preferences that have to be stored both locally and remotely, I was investigating the available Rails gems for user preferences and really didn’t like what was presently out there. I don’t really have time to maintain another gem, but maybe someone else has run into this problem and wants a quick and easy solution for creating user preferences. If so, then this code’s for you.

You might note that the value of all preferences, regardless of if they’re supposed to be Boolean or datetime, is a string. Keep this in mind when you have to query this field later. (That is, if you want to search for all preferences where the value is true, you’ll want to search for “1”. And similarly, doing user.preferences.first.true? will always return true, as any string value is true. So, coder beware!)

Using Them

Simple but straightforward: we include the module and then define each preference, with its name first and default value second. Ideally we don’t want to save default values to the database, since that would just make a lot of unnecessary records.

The Preferences Module

So let’s make that happen in that include Preferences line! This is the real heart of the preferences engine.

This is really pretty simple. Upon inclusion it tells the model that it’s a part of that it has_many :preferences and sets up a class variable hash to store preferences and their defaults. When you declare preference :chime, true it records that in the class variable, and then all instances will respond to either user.chime = true or user.write_preference(:chime, true). You can read values with user.chime or user.read_preference(:chime). If a value isn’t written in the database, it returns the default value instead.

This probably has a level or two of refactoring that could happen around it. Maybe when I have time I will turn it into a more sensible gem, but until then, if anyone needs quick and dirty preferences… here you go.

Josh Symonds performs devops and server wrangling on cloud-scale infrastructures, deploys amazing web applications with Ruby on Rails, and creates awesome iOS apps with Objective-C and RubyMotion. He is founder and CTO of Symonds & Son, a development shop focused on quality and excellence.