Class: Vanity::Configuration

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

Overview

This class holds the “how” Vanity operates. For the “what”, please see Vanity::Playground.

Defined Under Namespace

Classes: MissingEnvironment

Constant Summary collapse

LEGACY_CONNECTION_KEY =
:connection
LEGACY_REDIS_CONFIG_FILE =
"redis.yml"
DEFAULTS =
{
  add_participant_route: "/vanity/add_participant",
  collecting: true,
  config_file: "vanity.yml",
  config_path: File.join(Pathname.new("."), "config"),
  environment: ENV["RACK_ENV"] || ENV["RAILS_ENV"] || "development",
  experiments_path: File.join(Pathname.new("."), "experiments"),
  failover_on_datastore_error: false,
  locales_path: File.expand_path(File.join(File.dirname(__FILE__), 'locales')),
  logger: default_logger,
  on_datastore_error: lambda { |error, klass, method, arguments|
    default_on_datastore_error(error, klass, method, arguments)
  },
  on_assignment: nil,
  request_filter: ->(request) { default_request_filter(request) },
  templates_path: File.expand_path(File.join(File.dirname(__FILE__), 'templates')),
  use_js: false,
  experiments_start_enabled: true,
  cookie_name: 'vanity_id',
  cookie_expires: 20 * 365 * 24 * 60 * 60, # 20 years, give or take.
  cookie_domain: nil,
  cookie_path: nil,
  cookie_secure: false,
  cookie_httponly: false,
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#add_participant_route=(value) ⇒ Object (writeonly)

URL to the add_participant action.


72
73
74
# File 'lib/vanity/configuration.rb', line 72

def add_participant_route=(value)
  @add_participant_route = value
end

#collecting=(value) ⇒ Object (writeonly)

True if saving results to the datastore (participants and conversions).


66
67
68
# File 'lib/vanity/configuration.rb', line 66

def collecting=(value)
  @collecting = value
end

#config_file=(value) ⇒ Object (writeonly)

By default the vanity.yml file in the config_path variable. Variables scoped under the key for the current environment are extracted for the connection parameters. If there is no config/vanity.yml file, tries the configuration from config/redis.yml.


159
160
161
# File 'lib/vanity/configuration.rb', line 159

def config_file=(value)
  @config_file = value
end

#config_path=(value) ⇒ Object (writeonly)

Uses ./config by default.


154
155
156
# File 'lib/vanity/configuration.rb', line 154

def config_path=(value)
  @config_path = value
end

Cookie domain. By default nil. If domain is nil then the domain from Rails.application.config.session_options will be substituted.


174
175
176
# File 'lib/vanity/configuration.rb', line 174

def cookie_domain=(value)
  @cookie_domain = value
end

Cookie duration. By default 20 years.


170
171
172
# File 'lib/vanity/configuration.rb', line 170

def cookie_expires=(value)
  @cookie_expires = value
end

Cookie path. If true, cookie will not be available to JS. By default false.


183
184
185
# File 'lib/vanity/configuration.rb', line 183

def cookie_httponly=(value)
  @cookie_httponly = value
end

Cookie name. By default 'vanity_id'


167
168
169
# File 'lib/vanity/configuration.rb', line 167

def cookie_name=(value)
  @cookie_name = value
end

Cookie path. By default nil.


177
178
179
# File 'lib/vanity/configuration.rb', line 177

def cookie_path=(value)
  @cookie_path = value
end

Cookie secure. If true, cookie will only be transmitted to SSL pages. By default false.


180
181
182
# File 'lib/vanity/configuration.rb', line 180

def cookie_secure=(value)
  @cookie_secure = value
end

#environment=(value) ⇒ Object (writeonly)

In order of precedence, RACK_ENV, RAILS_ENV or `development`.


161
162
163
# File 'lib/vanity/configuration.rb', line 161

def environment=(value)
  @environment = value
end

#experiments_path=(value) ⇒ Object (writeonly)

Path to load experiment files from.


69
70
71
# File 'lib/vanity/configuration.rb', line 69

def experiments_path=(value)
  @experiments_path = value
end

#experiments_start_enabled=(value) ⇒ Object (writeonly)

By default experiments start enabled. If you want experiments to be explicitly enabled after a production release, then set to false.


164
165
166
# File 'lib/vanity/configuration.rb', line 164

def experiments_start_enabled=(value)
  @experiments_start_enabled = value
end

#failover_on_datastore_error=(value) ⇒ Object (writeonly)

Turns on passing of errors to the Proc returned by #on_datastore_error. Set `config.failover_on_datastore_error` to `true` to turn this on.

Since:

  • 2.0.0


83
84
85
# File 'lib/vanity/configuration.rb', line 83

def failover_on_datastore_error=(value)
  @failover_on_datastore_error = value
end

#locales_path=(value) ⇒ Object (writeonly)

Path to Vanity locales. Set this to override those in the gem.


131
132
133
# File 'lib/vanity/configuration.rb', line 131

def locales_path=(value)
  @locales_path = value
end

#logger=(value) ⇒ Object (writeonly)

Logger. The default logs to STDOUT.


75
76
77
# File 'lib/vanity/configuration.rb', line 75

def logger=(value)
  @logger = value
end

#on_assignment=(value) ⇒ Object (writeonly)

Default callback on assigment


186
187
188
# File 'lib/vanity/configuration.rb', line 186

def on_assignment=(value)
  @on_assignment = value
end

#on_datastore_error=(value) ⇒ Object (writeonly)

Must return a Proc that accepts as parameters: the thrown error, the calling Class, the calling method, and an array of arguments passed to the calling method. The return value is ignored.

The default implementation logs this information to Playground#logger.

Set a custom action by calling config.on_datastore_error = Proc.new { … }.

Examples:

Proc.new do |error, klass, method, arguments|
  ...
end

Since:

  • 2.0.0


100
101
102
# File 'lib/vanity/configuration.rb', line 100

def on_datastore_error=(value)
  @on_datastore_error = value
end

#request_filter=(value) ⇒ Object (writeonly)

Must return a Proc that accepts as a parameter the request object, if made available by the implement framework. The return value should be a boolean whether to ignore the request. This is called only for the JS callback action.

The default implementation does a simple test of whether the request's HTTP_USER_AGENT header contains a URI, or the words 'bot', 'crawler', or 'spider' since well behaved bots typically include a reference URI in their user agent strings. (Original idea: stackoverflow.com/a/9285889.)

Alternatively, one could filter an explicit list of IPs, add additional user agent strings to filter, or any custom test. Set a custom filter by calling config.request_filter = Proc.new { … }.

Examples:

Proc.new do |request|
  ...
end

Since:

  • 2.0.0


125
126
127
# File 'lib/vanity/configuration.rb', line 125

def request_filter=(value)
  @request_filter = value
end

#templates_path=(value) ⇒ Object (writeonly)

Path to Vanity templates. Set this to override those in the gem.


128
129
130
# File 'lib/vanity/configuration.rb', line 128

def templates_path=(value)
  @templates_path = value
end

#use_js=(value) ⇒ Object (writeonly)

Call to indicate that participants should be added via js. This helps keep robots from participating in the A/B test and skewing results.

If you want to use this:

  • Add <%= vanity_js %> to any page that needs uses an ab_test. vanity_js needs to be included after your call to ab_test so that it knows which version of the experiment the participant is a member of. The helper will render nothing if the there are no ab_tests running on the current page, so adding vanity_js to the bottom of your layouts is a good option. Keep in mind that if you set config.use_js = true and don't include vanity_js in your view no participants will be recorded.

Note that a custom JS callback path can be set using:

  • Set config.add_participant_route = '/path/to/vanity/action', this should point to the add_participant path that is added with Vanity::Rails::Dashboard, make sure that this action is available to all users.


152
153
154
# File 'lib/vanity/configuration.rb', line 152

def use_js=(value)
  @use_js = value
end

Instance Method Details

#[](arg) ⇒ Object


197
198
199
200
201
202
203
# File 'lib/vanity/configuration.rb', line 197

def [](arg)
  if instance_variable_defined?("@#{arg}")
    instance_variable_get("@#{arg}")
  else
    DEFAULTS[arg]
  end
end

#connection_params(file_name = nil) ⇒ Object

Returns nil or a hash of symbolized keys for connection settings.

Returns:

  • nil or a hash of symbolized keys for connection settings


211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/vanity/configuration.rb', line 211

def connection_params(file_name = nil)
  file_name ||= config_file
  file_path = File.join(config_path, file_name)

  if File.exist?(file_path) # rubocop:todo Style/GuardClause
    config = YAML.safe_load(ERB.new(File.read(file_path)).result, [], [], true)
    config ||= {}
    params_for_environment = config[environment.to_s]

    raise MissingEnvironment, "No configuration for #{environment}" unless params_for_environment

    # Symbolize keys if it's a hash.
    if params_for_environment.respond_to?(:inject)
      params_for_environment.each_with_object({}) do |kv, h|
        h[kv.first.to_sym] = kv.last
      end
    else
      params_for_environment
    end
  end
end

#connection_urlObject

Deprecated.

234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/vanity/configuration.rb', line 234

def connection_url
  connection_config = connection_params

  return unless connection_config && connection_config.respond_to?(:has_key?)

  connection_url = connection_config[LEGACY_CONNECTION_KEY]

  if connection_url # rubocop:todo Style/GuardClause
    logger.warn('Deprecated: Please specify connection urls using the `url` key with a protocol prefix instead of `connection`. This fallback will be removed in a future version.')

    # Legacy lack of protocol handling
    if /^\w+:/.match?(connection_url)
      connection_url
    else
      "redis://" + connection_url
    end
  end
end

#redis_url_from_fileObject

Deprecated.

254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/vanity/configuration.rb', line 254

def redis_url_from_file
  connection_url = connection_params(LEGACY_REDIS_CONFIG_FILE)

  if connection_url # rubocop:todo Style/GuardClause
    logger.warn('Deprecated: Please specify the vanity config file, the default fallback to "config/redis.yml" may be removed in a future version.')

    if /^\w+:/.match?(connection_url)
      connection_url
    else
      "redis://" + connection_url
    end
  end
end

#setup_localesObject


205
206
207
208
# File 'lib/vanity/configuration.rb', line 205

def setup_locales
  locales = Dir[File.join(locales_path, '*.{rb,yml}')]
  I18n.load_path += locales
end