Usually application data is stored in the DB. We use controllers and models to read and write it. But sometimes that data is static (system settings, list of countries, etc) so it does not make sense to put it in DB. Plus storing data in file(s) guarantees that when we deploy the application, the data will be there. Otherwise we have enter it manually via UI or load via SQL script.
There are several gems our there such as rails-settings and config. Usually I am big fan of using robust libraries instead of implementing complex functionality myself. But when the need is simple it can be better to create few config files / POROs to do exactly what we need.
Let’s imagine a CMS where users belong to various roles (admin, editor, author). We could create
Role model/table and have
UserRole mapping. Or we can store config values in
application.rb and have
But with time
application.rb gets bigger and harder to manage. Why not create a custom initializer?
CMS_ROLES is a constant so we want to give it descriptive name or namespace it.
What if the amount of data is much larger than a few strings? We might need to store the list of US states, zipcodes, countries, etc. Why not create
data folder in application root? We can put CSV, TXT, JSON, XML or YML files in appropriate subfolder structure.
Sharing data across multiple applications
Config values might need to be shared by several applications running on separate servers. But we do not want to store the same data files in multiple applications because they can get out of sync. We want a canonical source that gets refreshed everytime we deploy the main app. We could use Redis as a shared cache storage.
Now all we have do do in the second application is connect to Redis and read data.
One downside with this approach is that we need to restart the application(s) to force reload of
STATES_PROVINCES from Redis. We might want a hybrid option where we can edit data in Redis for live update and separately store canonical data in config file that gets deployed. We can use
REDIS_SETTINGS.smembers('states_provinces') in our code as is but that’s a little verbose.
Now we just call
RedSet.states_provinces from our application(s) and it will fetch data from Redis.
Depending on the type of data that needs to be cached in Redis we might use different data types. To store array of US states we used Redis SET with SADD and SMEMBERS commands. Other data might be better stored in Redis hashes, lists or strings.
If this approach does not work, there is redis-settings gem.