Class: FoodsoftConfig

Inherits:
Object
  • Object
show all
Defined in:
lib/foodsoft_config.rb

Overview

Foodcoop-specific configuration.

This is loaded from config/app_config.yml, which contains a root key for each environment (plus an optional defaults key). When using the multicoops feature (+multicoops+ is set to true for the environment), each foodcoop has its own key.

In addition to the configuration file, values can be overridden in the database using RailsSettings::CachedSettings as foodcoop.<foodcoop_scope>.**.

Some values may not be set in the database (e.g. the database connection to sharedlists, or default_scope), these are defined as children of the protected key. The default contains a sensible list, but you can modify that. Here's an almost minimal example:

default:
  default_scope: f
  host: order.foodstuff.test      # hostname for urls in emails

  name: Fairy Foodstuff           # the name of our foodcoop
  contact:
    # ...
    email: [email protected]   # general contact email address

  price_markup: 6                 # foodcoop margin

  protected:
    shared_lists: false           # allow database connection override
    use_messages: true            # foodcoops can't disable the use of messages

When you like to whitelist protected attributes, define an entry all: true, then you can whitelist specific attributes setting them to false.

Defined Under Namespace

Modules: DistributionStrategy

Constant Summary collapse

APP_CONFIG_FILE =

Configuration file location. Taken from environment variable FOODSOFT_APP_CONFIG, or else config/app_config.yml.

ENV.fetch('FOODSOFT_APP_CONFIG', 'config/app_config.yml')
APP_CONFIG =

Loaded configuration

ActiveSupport::HashWithIndifferentAccess.new

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Attribute Details

#configActiveSupport::HashWithIndifferentAccess

Returns a Hash with the current scope's configuration from the configuration file. Note that this does not include values that were changed in the database.

Returns:

  • (ActiveSupport::HashWithIndifferentAccess)

    Current configuration from configuration file.



45
# File 'lib/foodsoft_config.rb', line 45

mattr_accessor :config

#scopeString

Returns the current foodcoop scope for the multicoops feature, otherwise the value of the foodcoop configuration key default_scope is used.

Returns:

  • (String)

    The current foodcoop scope.



39
# File 'lib/foodsoft_config.rb', line 39

mattr_accessor :scope

Class Method Details

.[](key) ⇒ Object Also known as: read_attribute_for_serialization

Return configuration value for the currently selected foodcoop.

First tries to read configuration from the database (cached), then from the configuration files.

FoodsoftConfig[:name] # => 'FC Test'

To avoid errors when the database is not yet setup (when loading the initial database schema), cached settings are only being read when the settings table exists.

Parameters:

  • key (String, Symbol)

Returns:

  • (Object)

    Value of the key.



118
119
120
121
122
123
124
125
126
# File 'lib/foodsoft_config.rb', line 118

def [](key)
  if RailsSettings::CachedSettings.table_exists? && allowed_key?(key)
    value = RailsSettings::CachedSettings["foodcoop.#{scope}.#{key}"]
    value = config[key] if value.nil?
    value
  else
    config[key]
  end
end

.[]=(key, value) ⇒ Object

Store configuration in the database.

If value is equal to what's defined in the configuration file, remove key from the database.

Parameters:

  • key (String, Symbol)

    Key

  • value (Object)

    Value



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/foodsoft_config.rb', line 133

def []=(key, value)
  return unless allowed_key?(key)

  value = normalize_value value
  # then update database
  if config[key] == value || (config[key].nil? && value == false)
    # delete (ok if it was already deleted)
    begin
      RailsSettings::CachedSettings.destroy "foodcoop.#{scope}.#{key}"
    rescue RailsSettings::Settings::SettingNotFound
      # Setting not found, do nothing
    end
  else
    # or store
    RailsSettings::CachedSettings["foodcoop.#{scope}.#{key}"] = value
  end
end

.allowed_foodcoop?(foodcoop) ⇒ Boolean

Returns:

  • (Boolean)


176
177
178
# File 'lib/foodsoft_config.rb', line 176

def allowed_foodcoop?(foodcoop)
  foodcoops.include? foodcoop
end

.allowed_key?(key) ⇒ Boolean

Returns Whether this key may be set in the database.

Returns:

  • (Boolean)

    Whether this key may be set in the database



181
182
183
184
185
186
187
188
189
# File 'lib/foodsoft_config.rb', line 181

def allowed_key?(key)
  # fast check for keys without nesting
  if config[:protected].include? key
    !config[:protected][key]
  else
    !config[:protected][:all]
  end
  # @todo allow to check nested keys as well
end

.each_coopObject

Loop through each foodcoop and executes the given block after setup config and database



169
170
171
172
173
174
# File 'lib/foodsoft_config.rb', line 169

def each_coop
  foodcoops.each do |coop|
    select_multifoodcoop coop
    yield coop
  end
end

.foodcoopsArray<String>

Returns Valid names of foodcoops.

Returns:

  • (Array<String>)

    Valid names of foodcoops.



160
161
162
163
164
165
166
# File 'lib/foodsoft_config.rb', line 160

def foodcoops
  if config[:multi_coop_install]
    APP_CONFIG.keys.grep_v(/^(default|development|test|production)$/)
  else
    [config[:default_scope]]
  end
end

.init(filename = APP_CONFIG_FILE) ⇒ Object

Load and initialize foodcoop configuration file.

Parameters:

  • filename (String) (defaults to: APP_CONFIG_FILE)

    Override configuration file



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/foodsoft_config.rb', line 65

def init(filename = APP_CONFIG_FILE)
  Rails.logger.info "Loading app configuration from #{APP_CONFIG_FILE}"
  APP_CONFIG.clear.merge! YAML.load(ERB.new(File.read(File.expand_path(filename, Rails.root))).result)
  # Gather program-default configuration
  self.default_config = initial_default_config
  # Load initial config from development or production
  setup_config Rails.env
  # Overwrite scope to have a better namescope than 'production'
  self.scope = config[:default_scope] or raise 'No default_scope is set'
  # Set defaults for backward-compatibility
  set_missing
  # Make sure relevant configuration is applied, also in single coops mode,
  # where select_foodcoop is not called in every request.
  setup_mailing
end

.init_mailingObject



81
82
83
84
85
# File 'lib/foodsoft_config.rb', line 81

def init_mailing
  %i[protocol host port script_name].each do |k|
    ActionMailer::Base.default_url_options[k] = self[k] if self[k]
  end
end

.keysArray<String>

Returns Configuration keys that are set (either in app_config.yml or database).

Returns:

  • (Array<String>)

    Configuration keys that are set (either in app_config.yml or database).



152
153
154
155
156
157
# File 'lib/foodsoft_config.rb', line 152

def keys
  keys = RailsSettings::CachedSettings.get_all("foodcoop.#{scope}.").try(:keys) || []
  keys.map! { |k| k.gsub(/^foodcoop\.#{scope}\./, '') }
  keys += config.keys
  keys.map(&:to_s).uniq
end

.select_default_foodcoopObject



97
98
99
# File 'lib/foodsoft_config.rb', line 97

def select_default_foodcoop
  select_foodcoop config[:default_scope]
end

.select_foodcoop(foodcoop) ⇒ Object

Set config and database connection for specific foodcoop.

Only needed in multi coop mode.

Parameters:

  • foodcoop (String, Symbol)

    Foodcoop to select.



91
92
93
94
95
# File 'lib/foodsoft_config.rb', line 91

def select_foodcoop(foodcoop)
  setup_config foodcoop
  setup_database
  setup_mailing
end

.select_multifoodcoop(foodcoop) ⇒ Object



101
102
103
# File 'lib/foodsoft_config.rb', line 101

def select_multifoodcoop(foodcoop)
  select_foodcoop foodcoop if config[:multi_coop_install]
end

.to_hashHash

Returns Full configuration.

Returns:

  • (Hash)

    Full configuration.



192
193
194
# File 'lib/foodsoft_config.rb', line 192

def to_hash
  keys.index_with { |k| self[k] }
end