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 !