propensity 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.md +59 -0
- data/Rakefile +40 -0
- data/app/models/app_configuration.rb +7 -0
- data/app/models/propensity/preference.rb +5 -0
- data/app/models/propensity/preferences/configuration.rb +73 -0
- data/app/models/propensity/preferences/preferable.rb +141 -0
- data/app/models/propensity/preferences/preferable_class_methods.rb +89 -0
- data/app/models/propensity/preferences/store.rb +74 -0
- data/db/migrate/20120910124552_create_propensity_preferences.rb +15 -0
- data/lib/generators/propensity/install/install_generator.rb +18 -0
- data/lib/generators/propensity/install/templates/app_configuration.rb +7 -0
- data/lib/generators/propensity/install/templates/app_configuration.yml +0 -0
- data/lib/generators/propensity/install/templates/configuration_initializer.rb +0 -0
- data/lib/propensity/engine.rb +9 -0
- data/lib/propensity/environment.rb +11 -0
- data/lib/propensity/environment_extension.rb +23 -0
- data/lib/propensity/version.rb +3 -0
- data/lib/propensity.rb +3 -0
- data/lib/tasks/propensity_tasks.rake +4 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config/application.rb +59 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +4 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/fixtures/propensity/preferences.yml +17 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/propensity_test.rb +7 -0
- data/test/test_helper.rb +15 -0
- data/test/unit/propensity/preference_test.rb +9 -0
- metadata +147 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2012 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
Propensity
|
2
|
+
==========
|
3
|
+
|
4
|
+
Note: This gem is still under development, but is usable, and I have used it in production systems. Ensure that you follow the instructions in their entirety.
|
5
|
+
|
6
|
+
Propensity provides an easy way to manage settings within a Rails application. These settings are persisted in a database and loaded on initialization of Rails. This gem is simple, and does not contain any administrative UI.
|
7
|
+
|
8
|
+
Usage
|
9
|
+
-------
|
10
|
+
|
11
|
+
To install propensity, add the following to your Gemfile
|
12
|
+
|
13
|
+
```
|
14
|
+
gem 'propensity', git: "https://github.com/entropillc/propensity.git"
|
15
|
+
```
|
16
|
+
|
17
|
+
Note that I use Ruby 1.9.x syntax above, because it rocks, and the code uses 1.9.3 conventions. Once your Gemfile is updated make sure you install your new bundle
|
18
|
+
|
19
|
+
```
|
20
|
+
bundle install
|
21
|
+
```
|
22
|
+
|
23
|
+
After bundling, you're ready to run the installation generator
|
24
|
+
|
25
|
+
```
|
26
|
+
rails g propensity:install
|
27
|
+
```
|
28
|
+
|
29
|
+
Running the installer will copy the migrations in to your db/migrations folder and add an app_configuration.rb file to your models folder. Within app_configuration.rb you will specify your preferences.
|
30
|
+
|
31
|
+
There is one piece of magic that isn't completed yet that will require you to initialize Propensity on application startup. To do this, add the following code in your application.rb file:
|
32
|
+
|
33
|
+
```
|
34
|
+
# Initializing MyApplications Application Settings
|
35
|
+
initializer "application.environment", :before => :load_config_initializers do |app|
|
36
|
+
config.my_application = Propensity::Environment.new
|
37
|
+
MyApplication::Config = config.my_application.preferences
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
Configuring Your Settings
|
42
|
+
-------
|
43
|
+
|
44
|
+
The app_configuraiton.rb file in the models folder is where you will define your preferences. An example may look something like this:
|
45
|
+
|
46
|
+
```
|
47
|
+
class AppConfiguration < Propensity::Preferences::Configuration
|
48
|
+
|
49
|
+
preference :blog_title, :string, default: "My Blog Title"
|
50
|
+
preference :hours_in_a_day, :integer, default: 24
|
51
|
+
preference :am_i_crazy, :boolean, default: true
|
52
|
+
|
53
|
+
end
|
54
|
+
```
|
55
|
+
|
56
|
+
Credits
|
57
|
+
-------
|
58
|
+
|
59
|
+
I've always liked the way Spree (https://github.com/spree/spree) stored configuration settings and thought to myself "Self, you should really break that out so you can use it in other projects". So here it is, most of the code and ideas came from the Spree team. I liked their work, so I gemed it up.
|
data/Rakefile
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'Propensity'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
24
|
+
load 'rails/tasks/engine.rake'
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
Bundler::GemHelper.install_tasks
|
29
|
+
|
30
|
+
require 'rake/testtask'
|
31
|
+
|
32
|
+
Rake::TestTask.new(:test) do |t|
|
33
|
+
t.libs << 'lib'
|
34
|
+
t.libs << 'test'
|
35
|
+
t.pattern = 'test/**/*_test.rb'
|
36
|
+
t.verbose = false
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
task :default => :test
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# This takes the preferrable methods and adds some
|
2
|
+
# syntatic sugar to access the preferences
|
3
|
+
#
|
4
|
+
# class App < Configuration
|
5
|
+
# preference :color, :string
|
6
|
+
# end
|
7
|
+
#
|
8
|
+
# a = App.new
|
9
|
+
#
|
10
|
+
# setters:
|
11
|
+
# a.color = :blue
|
12
|
+
# a[:color] = :blue
|
13
|
+
# a.set :color = :blue
|
14
|
+
# a.preferred_color = :blue
|
15
|
+
#
|
16
|
+
# getters:
|
17
|
+
# a.color
|
18
|
+
# a[:color]
|
19
|
+
# a.get :color
|
20
|
+
# a.preferred_color
|
21
|
+
#
|
22
|
+
#
|
23
|
+
module Propensity
|
24
|
+
module Preferences
|
25
|
+
class Configuration
|
26
|
+
include Preferences::Preferable
|
27
|
+
|
28
|
+
def configure
|
29
|
+
yield(self) if block_given?
|
30
|
+
end
|
31
|
+
|
32
|
+
def preference_cache_key(name)
|
33
|
+
[self.class.name, name].join('::').underscore
|
34
|
+
end
|
35
|
+
|
36
|
+
def reset
|
37
|
+
preferences.each do |name, value|
|
38
|
+
set_preference name, preference_default(name)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
alias :[] :get_preference
|
43
|
+
alias :[]= :set_preference
|
44
|
+
|
45
|
+
alias :get :get_preference
|
46
|
+
|
47
|
+
def set(*args)
|
48
|
+
options = args.extract_options!
|
49
|
+
options.each do |name, value|
|
50
|
+
set_preference name, value
|
51
|
+
end
|
52
|
+
|
53
|
+
if args.size == 2
|
54
|
+
set_preference args[0], args[1]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def method_missing(method, *args)
|
59
|
+
name = method.to_s.gsub('=', '')
|
60
|
+
if has_preference? name
|
61
|
+
if method.to_s =~ /=$/
|
62
|
+
set_preference(name, args.first)
|
63
|
+
else
|
64
|
+
get_preference name
|
65
|
+
end
|
66
|
+
else
|
67
|
+
super
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
# The preference_cache_key is used to determine if the preference
|
2
|
+
# can be set. The default behavior is to return nil if there is no
|
3
|
+
# id value. On ActiveRecords, new objects will have their preferences
|
4
|
+
# saved to a pending hash until it is persisted.
|
5
|
+
#
|
6
|
+
# class_attributes are inheritied unless you reassign them in
|
7
|
+
# the subclass, so when you inherit a Preferable class, the
|
8
|
+
# inherited hook will assign a new hash for the subclass definitions
|
9
|
+
# and copy all the definitions allowing the subclass to add
|
10
|
+
# additional defintions without affecting the base
|
11
|
+
module Propensity
|
12
|
+
module Preferences
|
13
|
+
module Preferable
|
14
|
+
|
15
|
+
def self.included(base)
|
16
|
+
base.class_eval do
|
17
|
+
extend Preferences::PreferableClassMethods
|
18
|
+
|
19
|
+
if respond_to?(:after_create)
|
20
|
+
after_create do |obj|
|
21
|
+
obj.save_pending_preferences
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
if respond_to?(:after_destroy)
|
26
|
+
after_destroy do |obj|
|
27
|
+
obj.clear_preferences
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_preference(name)
|
35
|
+
has_preference! name
|
36
|
+
send self.class.preference_getter_method(name)
|
37
|
+
end
|
38
|
+
alias :preferred :get_preference
|
39
|
+
alias :prefers? :get_preference
|
40
|
+
|
41
|
+
def set_preference(name, value)
|
42
|
+
has_preference! name
|
43
|
+
send self.class.preference_setter_method(name), value
|
44
|
+
end
|
45
|
+
|
46
|
+
def preference_type(name)
|
47
|
+
has_preference! name
|
48
|
+
send self.class.preference_type_getter_method(name)
|
49
|
+
end
|
50
|
+
|
51
|
+
def preference_default(name)
|
52
|
+
has_preference! name
|
53
|
+
send self.class.preference_default_getter_method(name)
|
54
|
+
end
|
55
|
+
|
56
|
+
def preference_description(name)
|
57
|
+
has_preference! name
|
58
|
+
send self.class.preference_description_getter_method(name)
|
59
|
+
end
|
60
|
+
|
61
|
+
def has_preference!(name)
|
62
|
+
raise NoMethodError.new "#{name} preference not defined" unless has_preference? name
|
63
|
+
end
|
64
|
+
|
65
|
+
def has_preference?(name)
|
66
|
+
respond_to? self.class.preference_getter_method(name)
|
67
|
+
end
|
68
|
+
|
69
|
+
def preferences
|
70
|
+
prefs = {}
|
71
|
+
methods.grep(/^prefers_.*\?$/).each do |pref_method|
|
72
|
+
prefs[pref_method.to_s.gsub(/prefers_|\?/, '').to_sym] = send(pref_method)
|
73
|
+
end
|
74
|
+
prefs
|
75
|
+
end
|
76
|
+
|
77
|
+
def prefers?(name)
|
78
|
+
get_preference(name)
|
79
|
+
end
|
80
|
+
|
81
|
+
def preference_cache_key(name)
|
82
|
+
return unless id
|
83
|
+
[self.class.name, name, id].join('::').underscore
|
84
|
+
end
|
85
|
+
|
86
|
+
def save_pending_preferences
|
87
|
+
return unless @pending_preferences
|
88
|
+
@pending_preferences.each do |name, value|
|
89
|
+
set_preference(name, value)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def clear_preferences
|
94
|
+
preferences.keys.each {|pref| preference_store.delete preference_cache_key(pref)}
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
def add_pending_preference(name, value)
|
100
|
+
@pending_preferences ||= {}
|
101
|
+
@pending_preferences[name] = value
|
102
|
+
end
|
103
|
+
|
104
|
+
def get_pending_preference(name)
|
105
|
+
return unless @pending_preferences
|
106
|
+
@pending_preferences[name]
|
107
|
+
end
|
108
|
+
|
109
|
+
def convert_preference_value(value, type)
|
110
|
+
case type
|
111
|
+
when :string, :text
|
112
|
+
value.to_s
|
113
|
+
when :password
|
114
|
+
value.to_s
|
115
|
+
when :decimal
|
116
|
+
BigDecimal.new(value.to_s).round(2, BigDecimal::ROUND_HALF_UP)
|
117
|
+
when :integer
|
118
|
+
value.to_i
|
119
|
+
when :boolean
|
120
|
+
if value.is_a?(FalseClass) ||
|
121
|
+
value.nil? ||
|
122
|
+
value == 0 ||
|
123
|
+
value =~ /^(f|false|0)$/i ||
|
124
|
+
(value.respond_to? :empty? and value.empty?)
|
125
|
+
false
|
126
|
+
else
|
127
|
+
true
|
128
|
+
end
|
129
|
+
when :date
|
130
|
+
value.is_a?(Date) ? value : Date.parse(value)
|
131
|
+
else
|
132
|
+
value
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def preference_store
|
137
|
+
Propensity::Preferences::Store.instance
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Propensity
|
2
|
+
module Preferences
|
3
|
+
module PreferableClassMethods
|
4
|
+
|
5
|
+
def preference(name, type, *args)
|
6
|
+
options = args.extract_options!
|
7
|
+
options.assert_valid_keys(:default, :description)
|
8
|
+
default = options[:default]
|
9
|
+
description = options[:description] || name
|
10
|
+
|
11
|
+
# cache_key will be nil for new objects, then if we check if there
|
12
|
+
# is a pending preference before going to default
|
13
|
+
define_method preference_getter_method(name) do
|
14
|
+
if preference_cache_key(name) && preference_store.exist?(preference_cache_key(name))
|
15
|
+
preference_store.get preference_cache_key(name)
|
16
|
+
else
|
17
|
+
if get_pending_preference(name)
|
18
|
+
get_pending_preference(name)
|
19
|
+
else
|
20
|
+
send self.class.preference_default_getter_method(name)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
alias_method prefers_getter_method(name), preference_getter_method(name)
|
25
|
+
|
26
|
+
define_method preference_setter_method(name) do |value|
|
27
|
+
value = convert_preference_value(value, type)
|
28
|
+
if preference_cache_key(name)
|
29
|
+
preference_store.set preference_cache_key(name), value, type
|
30
|
+
else
|
31
|
+
add_pending_preference(name, value)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
alias_method prefers_setter_method(name), preference_setter_method(name)
|
35
|
+
|
36
|
+
define_method preference_default_getter_method(name) do
|
37
|
+
default
|
38
|
+
end
|
39
|
+
|
40
|
+
define_method preference_type_getter_method(name) do
|
41
|
+
type
|
42
|
+
end
|
43
|
+
|
44
|
+
define_method preference_description_getter_method(name) do
|
45
|
+
description
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def remove_preference(name)
|
50
|
+
remove_method preference_getter_method(name) if method_defined? preference_getter_method(name)
|
51
|
+
remove_method preference_setter_method(name) if method_defined? preference_setter_method(name)
|
52
|
+
remove_method prefers_getter_method(name) if method_defined? prefers_getter_method(name)
|
53
|
+
remove_method prefers_setter_method(name) if method_defined? prefers_setter_method(name)
|
54
|
+
remove_method preference_default_getter_method(name) if method_defined? preference_default_getter_method(name)
|
55
|
+
remove_method preference_type_getter_method(name) if method_defined? preference_type_getter_method(name)
|
56
|
+
remove_method preference_description_getter_method(name) if method_defined? preference_description_getter_method(name)
|
57
|
+
end
|
58
|
+
|
59
|
+
def preference_getter_method(name)
|
60
|
+
"preferred_#{name}".to_sym
|
61
|
+
end
|
62
|
+
|
63
|
+
def preference_setter_method(name)
|
64
|
+
"preferred_#{name}=".to_sym
|
65
|
+
end
|
66
|
+
|
67
|
+
def prefers_getter_method(name)
|
68
|
+
"prefers_#{name}?".to_sym
|
69
|
+
end
|
70
|
+
|
71
|
+
def prefers_setter_method(name)
|
72
|
+
"prefers_#{name}=".to_sym
|
73
|
+
end
|
74
|
+
|
75
|
+
def preference_default_getter_method(name)
|
76
|
+
"preferred_#{name}_default".to_sym
|
77
|
+
end
|
78
|
+
|
79
|
+
def preference_type_getter_method(name)
|
80
|
+
"preferred_#{name}_type".to_sym
|
81
|
+
end
|
82
|
+
|
83
|
+
def preference_description_getter_method(name)
|
84
|
+
"preferred_#{name}_description".to_sym
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# StoreInstance has a persistence flag that is on by default,
|
2
|
+
# but we disable database persistence in testing to speed up tests
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'singleton'
|
6
|
+
|
7
|
+
module Propensity
|
8
|
+
module Preferences
|
9
|
+
|
10
|
+
class StoreInstance
|
11
|
+
attr_accessor :persistence
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@cache = Rails.cache
|
15
|
+
@persistence = true
|
16
|
+
load_preferences
|
17
|
+
end
|
18
|
+
|
19
|
+
def set(key, value, type)
|
20
|
+
@cache.write(key, value)
|
21
|
+
persist(key, value, type)
|
22
|
+
end
|
23
|
+
|
24
|
+
def exist?(key)
|
25
|
+
@cache.exist? key
|
26
|
+
end
|
27
|
+
|
28
|
+
def get(key)
|
29
|
+
@cache.read(key)
|
30
|
+
end
|
31
|
+
|
32
|
+
def delete(key)
|
33
|
+
@cache.delete(key)
|
34
|
+
destroy(key)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def persist(cache_key, value, type)
|
40
|
+
return unless should_persist?
|
41
|
+
|
42
|
+
preference = Propensity::Preference.find_or_initialize_by_key(cache_key)
|
43
|
+
preference.value = value
|
44
|
+
preference.value_type = type
|
45
|
+
preference.save
|
46
|
+
end
|
47
|
+
|
48
|
+
def destroy(cache_key)
|
49
|
+
return unless should_persist?
|
50
|
+
|
51
|
+
preference = Propensity::Preference.find_by_key(cache_key)
|
52
|
+
preference.destroy if preference
|
53
|
+
end
|
54
|
+
|
55
|
+
def load_preferences
|
56
|
+
return unless should_persist?
|
57
|
+
|
58
|
+
Propensity::Preference.all.each do |p|
|
59
|
+
@cache.write(p.key, p.value)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def should_persist?
|
64
|
+
@persistence
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
class Store < StoreInstance
|
70
|
+
include Singleton
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class CreatePropensityPreferences < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :propensity_preferences do |t|
|
4
|
+
t.string :name
|
5
|
+
t.integer :owner_id
|
6
|
+
t.string :owner_type
|
7
|
+
t.text :value
|
8
|
+
t.string :key
|
9
|
+
t.string :value_type
|
10
|
+
t.timestamps
|
11
|
+
end
|
12
|
+
|
13
|
+
add_index :propensity_preferences, :key, :unique => true
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rails/generators/base'
|
2
|
+
|
3
|
+
module Propensity
|
4
|
+
module Generators
|
5
|
+
class InstallGenerator < ::Rails::Generators::Base
|
6
|
+
def self.source_root
|
7
|
+
@source ||= File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
|
8
|
+
end
|
9
|
+
|
10
|
+
desc "This generator Propensity in to a Rails application"
|
11
|
+
|
12
|
+
def add_configuration_and_initializers
|
13
|
+
copy_file "app_configuration.rb", "app/models/app_configuration.rb"
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
File without changes
|
File without changes
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Propensity
|
2
|
+
module EnvironmentExtension
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def add_class(name)
|
6
|
+
self.instance_variable_set "@#{name}", Set.new
|
7
|
+
|
8
|
+
create_method( "#{name}=".to_sym ) { |val|
|
9
|
+
instance_variable_set( "@" + name, val)
|
10
|
+
}
|
11
|
+
|
12
|
+
create_method(name.to_sym) do
|
13
|
+
instance_variable_get( "@" + name )
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def create_method(name, &block)
|
20
|
+
self.class.send(:define_method, name, &block)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/propensity.rb
ADDED