setler 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +16 -3
- data/Rakefile +1 -0
- data/lib/generators/setler/templates/model.rb +0 -1
- data/lib/setler/active_record.rb +1 -1
- data/lib/setler/scoped_settings.rb +3 -2
- data/lib/setler/settings.rb +21 -18
- data/lib/setler/version.rb +1 -1
- data/test/settings_test.rb +54 -35
- data/test/test_helper.rb +15 -0
- metadata +12 -12
data/README.rdoc
CHANGED
@@ -6,7 +6,7 @@ Setler is a Gem that lets one easily implement the "Feature Flags" pattern, or a
|
|
6
6
|
|
7
7
|
Install the gem by adding this to your Gemfile:
|
8
8
|
|
9
|
-
gem "setler"
|
9
|
+
gem "setler"
|
10
10
|
|
11
11
|
Generate the model:
|
12
12
|
|
@@ -20,13 +20,14 @@ Run the migration:
|
|
20
20
|
|
21
21
|
Create/Update settings:
|
22
22
|
|
23
|
+
# Method calls and []= are synonymous
|
23
24
|
Featureflags.bacon_dispenser_enabled = true
|
24
|
-
Settings
|
25
|
+
Settings[:allowed_meats] = ['bacon', 'crunchy bacon']
|
25
26
|
|
26
27
|
Read settings:
|
27
28
|
|
28
29
|
Featureflags.bacon_dispenser_enabled # true
|
29
|
-
Settings
|
30
|
+
Settings[:allowed_meats].include?('bacon') # true
|
30
31
|
|
31
32
|
Destroy them:
|
32
33
|
|
@@ -59,3 +60,15 @@ Then you get:
|
|
59
60
|
TODO: And look em up:
|
60
61
|
|
61
62
|
User.with_settings_for('favorite_meat') # => scope of users with the favorite_meat setting
|
63
|
+
|
64
|
+
== Gem Development
|
65
|
+
|
66
|
+
Getting started is pretty straightforward:
|
67
|
+
|
68
|
+
1. Check out the code: `git clone git://github.com/ckdake/setler.git`
|
69
|
+
2. Bundle install: `bundle install`
|
70
|
+
3. Run the tests and make sure they all pass and code coverage is still 100%: `rake test`
|
71
|
+
|
72
|
+
If you'd like to contribute code, make your changes and submit a pull request that includes appropriate tests
|
73
|
+
|
74
|
+
For building the gem: `rake build` and to release a gem to github and Rubygems: `rake release`
|
data/Rakefile
CHANGED
data/lib/setler/active_record.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
module Setler
|
2
2
|
class ScopedSettings < Settings
|
3
|
-
def self.for_thing(object)
|
3
|
+
def self.for_thing(object, scopename)
|
4
|
+
set_table_name scopename
|
4
5
|
@object = object
|
5
6
|
self
|
6
7
|
end
|
7
8
|
|
8
9
|
def self.thing_scoped
|
9
|
-
|
10
|
+
self.base_class.where(thing_type: @object.class.base_class.to_s, thing_id: @object.id)
|
10
11
|
end
|
11
12
|
|
12
13
|
end
|
data/lib/setler/settings.rb
CHANGED
@@ -3,8 +3,6 @@ module Setler
|
|
3
3
|
serialize :value
|
4
4
|
self.abstract_class = true
|
5
5
|
|
6
|
-
set_table_name 'settings'
|
7
|
-
|
8
6
|
cattr_accessor :defaults
|
9
7
|
@@defaults = {}.with_indifferent_access
|
10
8
|
|
@@ -15,26 +13,30 @@ module Setler
|
|
15
13
|
else
|
16
14
|
method_name = method.to_s
|
17
15
|
if method_name.ends_with?("=")
|
18
|
-
|
19
|
-
# thing_scoped.find_or_create_by_var(method_name[0..-2]) should work but doesnt for some reason
|
20
|
-
# When @object is present, thing_scoped sets the where scope for the polymorphic association
|
21
|
-
# but the find_or_create_by wasn't using the thing_type and thing_id
|
22
|
-
thing_scoped.find_or_create_by_var_and_thing_type_and_thing_id(
|
23
|
-
method_name[0..-2],
|
24
|
-
@object.try(:class).try(:base_class).try(:to_s),
|
25
|
-
@object.try(:id)
|
26
|
-
).update_attribute(:value, args.first)
|
16
|
+
self[method_name[0..-2]] = args.first
|
27
17
|
else
|
28
|
-
|
29
|
-
if the_setting.nil?
|
30
|
-
return @@defaults[method_name]
|
31
|
-
else
|
32
|
-
return the_setting.value
|
33
|
-
end
|
18
|
+
self[method_name]
|
34
19
|
end
|
35
20
|
end
|
36
21
|
end
|
37
|
-
|
22
|
+
|
23
|
+
def self.[](var)
|
24
|
+
the_setting = thing_scoped.find_by_var(var.to_s)
|
25
|
+
the_setting.try(:value) || @@defaults[var]
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.[]=(var, value)
|
29
|
+
# THIS IS BAD
|
30
|
+
# thing_scoped.find_or_create_by_var(method_name[0..-2]) should work but doesnt for some reason
|
31
|
+
# When @object is present, thing_scoped sets the where scope for the polymorphic association
|
32
|
+
# but the find_or_create_by wasn't using the thing_type and thing_id
|
33
|
+
thing_scoped.find_or_create_by_var_and_thing_type_and_thing_id(
|
34
|
+
var.to_s,
|
35
|
+
@object.try(:class).try(:base_class).try(:to_s),
|
36
|
+
@object.try(:id)
|
37
|
+
).update_attribute(:value, value)
|
38
|
+
end
|
39
|
+
|
38
40
|
def self.destroy(var_name)
|
39
41
|
var_name = var_name.to_s
|
40
42
|
if setting = self.find_by_var(var_name)
|
@@ -52,6 +54,7 @@ module Setler
|
|
52
54
|
def self.thing_scoped
|
53
55
|
self.where(thing_type: nil, thing_id: nil)
|
54
56
|
end
|
57
|
+
|
55
58
|
end
|
56
59
|
|
57
60
|
end
|
data/lib/setler/version.rb
CHANGED
data/test/settings_test.rb
CHANGED
@@ -1,67 +1,86 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
class
|
3
|
+
class ::SettingsTest < Test::Unit::TestCase
|
4
4
|
setup_db
|
5
5
|
|
6
6
|
def setup
|
7
|
-
|
8
|
-
|
7
|
+
::Settings.create(:var => 'test', :value => 'foo')
|
8
|
+
::Settings.create(:var => 'test2', :value => 'bar')
|
9
9
|
end
|
10
10
|
|
11
11
|
def teardown
|
12
|
-
|
12
|
+
::Settings.delete_all
|
13
|
+
::Preferences.delete_all
|
13
14
|
end
|
14
15
|
|
15
16
|
def test_defaults
|
16
|
-
|
17
|
+
::Settings.defaults[:foo] = 'default foo'
|
17
18
|
|
18
|
-
assert_equal 'default foo',
|
19
|
+
assert_equal 'default foo', ::Settings.foo
|
19
20
|
|
20
|
-
|
21
|
-
assert_equal 'bar',
|
21
|
+
::Settings.foo = 'bar'
|
22
|
+
assert_equal 'bar', ::Settings.foo
|
22
23
|
end
|
23
24
|
|
24
25
|
def tests_defaults_false
|
25
|
-
|
26
|
-
assert_equal false,
|
26
|
+
::Settings.defaults[:foo] = false
|
27
|
+
assert_equal false, ::Settings.foo
|
27
28
|
end
|
28
29
|
|
29
30
|
def test_get
|
30
|
-
assert_equal 'foo',
|
31
|
-
assert_equal 'bar',
|
31
|
+
assert_equal 'foo', ::Settings.test
|
32
|
+
assert_equal 'bar', ::Settings.test2
|
32
33
|
end
|
33
|
-
|
34
|
+
|
35
|
+
def test_get_with_array_syntax
|
36
|
+
assert_equal 'foo', ::Settings["test"]
|
37
|
+
assert_equal 'bar', ::Settings[:test2]
|
38
|
+
end
|
39
|
+
|
34
40
|
def test_update
|
35
|
-
|
36
|
-
assert_equal '321',
|
41
|
+
::Settings.test = '321'
|
42
|
+
assert_equal '321', ::Settings.test
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_update_with_array_syntax
|
46
|
+
::Settings["test"] = '321'
|
47
|
+
assert_equal '321', ::Settings.test
|
48
|
+
|
49
|
+
::Settings[:test] = '567'
|
50
|
+
assert_equal '567', ::Settings.test
|
37
51
|
end
|
38
52
|
|
39
53
|
def test_create
|
40
|
-
|
41
|
-
assert_equal '123',
|
54
|
+
::Settings.onetwothree = '123'
|
55
|
+
assert_equal '123', ::Settings.onetwothree
|
42
56
|
end
|
43
57
|
|
44
58
|
def test_complex_serialization
|
45
59
|
complex = [1, '2', {:three => true}]
|
46
|
-
|
47
|
-
assert_equal complex,
|
60
|
+
::Settings.complex = complex
|
61
|
+
assert_equal complex, ::Settings.complex
|
48
62
|
end
|
49
|
-
|
63
|
+
|
50
64
|
def test_serialization_of_float
|
51
|
-
|
52
|
-
|
53
|
-
assert_equal 0.01,
|
54
|
-
assert_equal 0.02,
|
65
|
+
::Settings.float = 0.01
|
66
|
+
::Settings.reload
|
67
|
+
assert_equal 0.01, ::Settings.float
|
68
|
+
assert_equal 0.02, ::Settings.float * 2
|
55
69
|
end
|
56
70
|
|
57
71
|
def test_all
|
58
|
-
assert_equal({ "test2" => "bar", "test" => "foo" },
|
72
|
+
assert_equal({ "test2" => "bar", "test" => "foo" }, ::Settings.all)
|
59
73
|
end
|
60
74
|
|
61
75
|
def test_destroy
|
62
|
-
assert_not_nil
|
63
|
-
|
64
|
-
assert_nil
|
76
|
+
assert_not_nil ::Settings.test
|
77
|
+
::Settings.destroy :test
|
78
|
+
assert_nil ::Settings.test
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_multiple_settings_classes
|
82
|
+
::Settings.testing = '123'
|
83
|
+
assert_nil ::Preferences.testing
|
65
84
|
end
|
66
85
|
|
67
86
|
def test_user_has_setler
|
@@ -72,21 +91,21 @@ class Setler::SettingsTest < Test::Unit::TestCase
|
|
72
91
|
user.preferences.destroy :likes_bacon
|
73
92
|
assert_nil user.preferences.likes_bacon
|
74
93
|
end
|
75
|
-
|
94
|
+
|
76
95
|
def test_user_settings_all
|
77
|
-
|
96
|
+
::Settings.destroy_all
|
78
97
|
user = User.create name: 'user 1'
|
79
|
-
assert_equal
|
98
|
+
assert_equal ::Settings.all, user.preferences.all
|
80
99
|
user.preferences.likes_bacon = true
|
81
100
|
user.preferences.really_likes_bacon = true
|
82
101
|
assert user.preferences.all['likes_bacon']
|
83
|
-
assert
|
102
|
+
assert !::Settings.all['likes_bacon']
|
84
103
|
assert user.preferences.all['really_likes_bacon']
|
85
|
-
assert
|
104
|
+
assert !::Settings.all['really_likes_bacon']
|
86
105
|
end
|
87
106
|
|
88
107
|
def test_user_settings_override_defaults
|
89
|
-
|
108
|
+
::Settings.defaults[:foo] = false
|
90
109
|
user = User.create name: 'user 1'
|
91
110
|
assert !user.preferences.foo
|
92
111
|
user.preferences.foo = true
|
@@ -105,7 +124,7 @@ class Setler::SettingsTest < Test::Unit::TestCase
|
|
105
124
|
|
106
125
|
def test_destroy_when_setting_does_not_exist
|
107
126
|
assert_raise Setler::SettingNotFound do
|
108
|
-
|
127
|
+
::Settings.destroy :not_a_setting
|
109
128
|
end
|
110
129
|
end
|
111
130
|
end
|
data/test/test_helper.rb
CHANGED
@@ -21,6 +21,12 @@ class User < ActiveRecord::Base
|
|
21
21
|
has_setler :preferences
|
22
22
|
end
|
23
23
|
|
24
|
+
class Settings < Setler::Settings
|
25
|
+
end
|
26
|
+
|
27
|
+
class Preferences < Setler::Settings
|
28
|
+
end
|
29
|
+
|
24
30
|
def setup_db
|
25
31
|
ActiveRecord::Schema.define(:version => 1) do
|
26
32
|
create_table :settings do |t|
|
@@ -32,6 +38,15 @@ def setup_db
|
|
32
38
|
end
|
33
39
|
add_index :settings, [ :thing_type, :thing_id, :var ], :unique => true
|
34
40
|
|
41
|
+
create_table :preferences do |t|
|
42
|
+
t.string :var, :null => false
|
43
|
+
t.text :value, :null => true
|
44
|
+
t.integer :thing_id, :null => true
|
45
|
+
t.string :thing_type, :limit => 30, :null => true
|
46
|
+
t.timestamps
|
47
|
+
end
|
48
|
+
add_index :preferences, [ :thing_type, :thing_id, :var ], :unique => true
|
49
|
+
|
35
50
|
create_table :users do |t|
|
36
51
|
t.string :name
|
37
52
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: setler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-12-04 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
16
|
-
requirement: &
|
16
|
+
requirement: &70335468202960 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 3.0.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70335468202960
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rails
|
27
|
-
requirement: &
|
27
|
+
requirement: &70335468202460 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 3.0.0
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70335468202460
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: sqlite3
|
38
|
-
requirement: &
|
38
|
+
requirement: &70335468202080 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70335468202080
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rake
|
49
|
-
requirement: &
|
49
|
+
requirement: &70335468231300 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70335468231300
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: cover_me
|
60
|
-
requirement: &
|
60
|
+
requirement: &70335468230880 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,7 +65,7 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70335468230880
|
69
69
|
description: Setler is a Gem that lets one easily implement the "Feature Flags" pattern,
|
70
70
|
or add settings to individual models. This is a cleanroom implementation of what
|
71
71
|
the 'rails-settings' gem does. It's been forked all over the place, and my favorite
|