Work with data in Yaml

The other day, I was solving the problem of storing data in a yaml file, with the ability for users to edit this data. Everything was a little complicated by the fact that users had different access rights. For each line that we store, information should be available on which users have access to edit this line.

Here is an example of such a settings file:

---
api_url:
  value: example.com/api
  role: 4
api_login:
  value: user
  role: 4
api_password:
  value: 12355
  role: 4


In this case, we have three variables that store information about access to the API. Each key is a hash to store the value of the variable and the minimum role of the user who has access to this data.

Now we will write a class that can read and edit this data, taking into account the rights of the user in the system.

require 'yaml'
class Setting
  CONFIG_FILE = 'settings.yml'
  class << self
    def get(key)
      load_settings[key.to_s]['value']
    end
    def update(params, role)
      settings = load_settings
      params.each do |key, value|
        key = key.to_s
        settings[key]['value'] = value.to_s if has_access?(role, key)
      end
      save_settings(settings)
    end
    def has_access?(role, key)
      return unless setting = load_settings[key]
      role >= setting['role']
    end
    def load_settings
      @config ||= YAML.load(File.read(file_path))
    end
    private
    def save_settings(settings)
      File.write(file_path, settings.to_yaml)
    end
    def file_path
      "config/#{CONFIG_FILE}"
    end
  end
end


Key data can be obtained as follows:
Setting.get('api_login')
Setting.get('api_password')
…


Data is updated taking into account user rights, that is, no checks outside the class are required. You can transfer just a hash with the data and updates will be made on the data that is available to the user for editing. This allows you to safely transfer all the data entered by the user:
Setting.update(params[:settings], current_user.role)


We pass a hash with the information that needs to be updated and the current user rights.

The method that stores the path to the settings file can be set more conveniently if you do this in Rails:
Rails.root.join('config', CONFIG_FILE)

Also popular now: