setler 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|