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.

Constant Summary collapse

APP_CONFIG_FILE =

Configuration file location.

Taken from environment variable +FOODSOFT_APP_CONFIG+,
or else +config/app_config.yml+.
ENV['FOODSOFT_APP_CONFIG'] || 'config/app_config.yml'
APP_CONFIG =

Loaded configuration

ActiveSupport::HashWithIndifferentAccess.new

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.default_configHash (protected)

Returns the program-default foodcoop configuration.

Plugins (engines in Rails terms) can easily add to the default configuration by defining a method default_foodsoft_config in their engine and modify the Hash passed.

When modifying this, please make sure to use default values that match old behaviour. For example, when the wiki was made optional and turned into a plugin, the configuration item use_wiki was introduced with a default value of true (set in the wiki plugin):

module FoodsoftWiki
   class Engine < ::Rails::Engine
     def default_foodsoft_config(cfg)
       cfg[:use_wiki] = true # keep backward compatibility
     end
   end
 end

Returns:

  • (Hash)

    Default configuration values


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

mattr_accessor :default_config

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.


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

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.


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

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.


111
112
113
114
115
116
117
118
119
# File 'lib/foodsoft_config.rb', line 111

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

.[]=(key, value) ⇒ Boolean

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

Returns:

  • (Boolean)

    Whether storing succeeded (fails when key is not allowed to be set in database).


127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/foodsoft_config.rb', line 127

def []=(key, value)
  return false 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.#{self.scope}.#{key}"
    rescue RailsSettings::Settings::SettingNotFound
    end
  else
    # or store
    RailsSettings::CachedSettings["foodcoop.#{self.scope}.#{key}"] = value
  end
  return true
end

.allowed_foodcoop?(foodcoop) ⇒ Boolean

Returns:

  • (Boolean)

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

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


174
175
176
177
178
179
180
181
182
# File 'lib/foodsoft_config.rb', line 174

def allowed_key?(key)
  # fast check for keys without nesting
  if self.config[:protected].include? key
    return !self.config[:protected][key]
  else
    return !self.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


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

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.


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

def foodcoops
  if config[:multi_coop_install]
    APP_CONFIG.keys.reject { |coop| coop =~ /^(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


61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/foodsoft_config.rb', line 61

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 = get_default_config
  # Load initial config from development or production
  set_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
end

.init_mailingObject


74
75
76
77
78
# File 'lib/foodsoft_config.rb', line 74

def init_mailing
  [: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).


145
146
147
148
149
150
# File 'lib/foodsoft_config.rb', line 145

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

.select_default_foodcoopObject


90
91
92
# File 'lib/foodsoft_config.rb', line 90

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.


84
85
86
87
88
# File 'lib/foodsoft_config.rb', line 84

def select_foodcoop(foodcoop)
  set_config foodcoop
  setup_database
  setup_mailing
end

.select_multifoodcoop(foodcoop) ⇒ Object


94
95
96
# File 'lib/foodsoft_config.rb', line 94

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

.to_hashHash

Returns Full configuration.

Returns:

  • (Hash)

    Full configuration.


185
186
187
# File 'lib/foodsoft_config.rb', line 185

def to_hash
  Hash[keys.map {|k| [k, self[k]]} ]
end