Skip to content Interested in a powerful Rails UI library?

Preflex - a Rails engine to manage any kind of user preferences/feature flags/etc.

Published on

Why would I use this?

A lot of apps at some point will run into a requirement where they need to store preferences for a user or some other app-specific model.

For example, you might want to store if a User on your app prefers autoplaying the next song or if they prefer the dark theme.

Similarly, you might have concept of a Store in your app where each store might have its own feature flag preferences.

Most straightforward solution to this would be to either just store these preferences on your existing model or create a new model that stores things according to your need. And then decide if you’d want to write a controller to allow client side updates, and perform AJAX requests for these updates.

Some cases would be able to just use localStorage for storing things client side but that has its own drawbacks - e.g things not being shared cross browser.

It’s not a big challenge, but still code you have to write and maintain.

I think there’s an opportunity to abstract all that away in an Engine whilst adding features that makes working with preferences like these simple and fun.

Preflex is a Rails Engine that allows you to do just that. It includes support for reading/writing preferences from the server (duh!) and client side (using JavaScript!). You install it, create your preference class and start using it.

Installation & Usage

You can checkout the README on GitHub to see how to install it and for more details, but it’s really just adding the gem to your Gemfile and running bundle exec rails preflex

Example

If you’ve already installed it, here’s an example to see how simple it really is:

## Say I need two preference models for storing different kind of preferences.
## One for storing feature flags that are scoped to an `Account` object in my app.
## And another for storing user-level preferences that are scoped to an `User` object.

# app/models/feature_flags.rb
class FeatureFlags < Preflex::Preference
  preference :new_navigation,   :boolean, default: false
  preference :email_builder_v2, :boolean, default: true

  def self.current_owner(controller_instance)
    controller_instance.current_account
  end
end

# app/models/user_preference.rb
class UserPreference < Preflex::Preference
  preference :dark_mode,     :boolean, default: false
  preference :playback_rate, :integer, default: 1

  def self.current_owner(controller_instance)
    controller_instance.current_user
  end
end


### That's it. Now I can do:
user = User.find(1)
UserPreference.for(user).get(:dark_mode)
UserPreference.for(user).set(:playback_rate, 2)

## And within context of a controller request, assuming you've
## defined `current_owner`, like I have above, you can just do:
UserPreference.current.get(:dark_mode)
UserPreference.current.set(:playback_rate, 2)

## Or more simply, just:
UserPreference.get(:dark_mode)
UserPreference.set(:playback_rate, 2)

And if you want to read/write values from JavaScript, include this script tag in your layout file:

<!--
  In your layout file
  E.g app/views/layouts/application.html.erb
-->
<html>
  <head>
    <%= Preflex::PreferencesHelper.script_tag(UserPreference, FeatureFlags, CustomerSettings) %>
    ...
  </head>
  ...
</html>

And then using JavaScript

console.log(UserPreference.get("playback_rate")); // => 2
console.log(UserPreference.get("dark_mode")); // => false

UserPreference.set("dark_mode", true);
console.log(UserPreference.get("dark_mode")); // => false

// You can also listen for change events
document.addEventListener("preflex:preference-updated", e => {
  console.log("Event detail:", e.detail);
});
UserPreference.set("playback_rate", 3);
// => Event detail: { klass: 'UserPreference', name: 'playback_rate', value: 3 }

Coming soon: The only Rails UI library you'll ever need

  • Includes a lot of components necessary to build a modern app
  • Dark mode support out of the box · Simple to customize & extend
  • Simple primitives as well as complex components - not "another UI library"
  • Patterns I've found incredibly useful over the past years working with Rails
  • Subscribe now to receive updates and a free preview

Questions/Issues

More documentation is available on the GitHub repository below, so check it out if you want more details.

If you’ve got any questions or issues, feel free to open an issues on the GitHub Repository.

GitHub: https://github.com/owaiswiz/preflex

Get more articles like this

Subscribe to my newsletter to get my latest blog posts, and other freebies like Treact, as soon as they get published !