simplificator-has_setting 0.3.9 → 0.4.0

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 ADDED
@@ -0,0 +1,104 @@
1
+ ==What is it?
2
+ has_setting is a simple extension that enables ActiveRecord models to
3
+ store settings in a separate settings table as key/value pairs where the key and value are stored as Strings.
4
+
5
+ ==History
6
+ * 0.3.10:
7
+ * added boolean and booleans formatters
8
+ * 0.3.9:
9
+ * added type :strings, :floats, :ints. They store the contents of an array as a comma separated string.
10
+ * 0.3.8:
11
+ * added dependent destroy option. no more zombie settings lingering around.
12
+ * 0.3.7:
13
+ * Gem is now built using jeweler... after messing around and bumping versions and getting
14
+ strange errors, this is 'it works' feeling coming back
15
+ * 0.3.4:
16
+ * Added custom formatter support. no new formatters though...
17
+ * 0.3.1:
18
+ * Bug Fixed: has_many(:settings) is not added to ActiveRecord::Base but only to the classes with has_setting
19
+ * Bug Fixed: options are not shared between classes
20
+ * Again changed the way settings are saved. Save is now done on parent.save with an after_save callback. (like this the settings are treated as if they were attributes of the owner)
21
+ * 0.2.x:
22
+ * Added :default option
23
+ * changed way settings are saved so that unsaved parents can have settings too
24
+ * changed nameing scheme of setting names (incompatible with versions prior 0.2.x but since nobody uses the gem i dont care :-))
25
+ * 0.1.x: First Version
26
+
27
+
28
+ ==Installation
29
+ sudo gem install simplificator-has_setting
30
+
31
+ ==Setup
32
+ * Add a migration that looks more or less like the one in <em>help/001_create_settings.rb</em>
33
+ * Make sure the gem is loaded when your application starts
34
+
35
+ ==Config
36
+ The model you want to hold settings (i.e. User, Profile, ...):
37
+ <tt>has_setting(:name_of_the_setting)</tt>
38
+ This will create the following methods for you on the owner class:
39
+ * <tt>name_of_the_setting=(value)</tt> a standard setter
40
+ * <tt>name_of_the_setting()</tt> a standard getter (the getter method takes an optional hash to override some options, possible values are the same as the options in has_setting())
41
+
42
+ <tt>has_setting(name, options)</tt> takes an optional hash of options. Following options are supported:
43
+ <em>:type</em> allows you to convert the value:
44
+ * <em>:string</em> (default) Uses the StringFormatter to convert from/to String (actually this formatter just leaves the value as it is)
45
+ * <em>:int</em> Uses the IntFormatter to convert from/to int values.
46
+ * <em>:boolean</em> Uses the BooleanFormatter to convert from/to boolean values.
47
+ * <em>:float</em> Uses the FloatFormatter to convert from/to float values.
48
+ * <em>:ints</em> Uses the IntsFormatter to convert from/to int[]
49
+ * <em>:floats</em> Uses the FloatsFormatter to convert from/to float[]
50
+ * <em>:strings</em> Uses the StringsFormatter to convert from/to string[]
51
+ * <em>:booleans</em> Uses the BooleansFormatter to convert from/to boolean[]
52
+ <em>:default</em> allows you to specify a default value that will be returned if the setting does not exist (i.e. has never been written). Note that the default value is _ignored_ if the setting exists, no matter what the value of the setting is. The default value is returned as is, no type conversion takes place.
53
+
54
+
55
+
56
+ ==How it works
57
+ A polymorphic parent-child relation is created between Setting and the parent/owning class.
58
+ Getters/setters are added through meta-programming-magic. If the setter is invoked on a unsafed parent then the setting is not saved until the parent is saved, else setting is saved upon creation (i.e. first time the setter is called) / change (subsequent calls).
59
+ The getters/setters can be used in standard AR validations, Rails mass assignments/form helpers and so on.
60
+
61
+ ==Gotchas
62
+ * Values are stored as Strings in the DB. Values are converted with one of the formatters (depending on selected :type). If you try to store an unsupported type or anything other than the type you selected there might be an exception (i.e. if you try to store "foobar" as an :type => :int)
63
+ * Currently there are no length validations on the 'name' and 'value' column of Setting. Take care not to store values to big. Especially when using the array formatters (:floats, :ints, :strings)
64
+
65
+
66
+ ==Example
67
+ <code>
68
+ class Foo < ActiveRecord::Base
69
+ has_setting(:string_setting)
70
+ has_setting(:another_string_setting, :type => :string)
71
+ has_setting(:int_setting, :type => :int)
72
+ has_setting(:float_setting, :type => :float, :default => 3.3)
73
+ end
74
+
75
+
76
+ foo = Foo.create
77
+
78
+ foo.string_setting
79
+ => nil
80
+ foo.string_setting= 'a string'
81
+ foo.string_setting
82
+ => 'a string'
83
+
84
+ foo.int_setting = 123
85
+ foo.int_setting
86
+ => 123
87
+ foo.int_setting = '123'
88
+ foo.int_setting
89
+ => 123
90
+
91
+ foo.float_setting
92
+ => 3.3
93
+ foo.float_setting = nil
94
+ foo.float_setting
95
+ => nil
96
+
97
+ </code>
98
+
99
+
100
+ ==Todo
101
+ has_setting should stay as simple as possible... still some ideas are around:
102
+ * Custom formatter (to convert arbitrary objects, i.e. Date/Time/DateTime...)
103
+ * Add validation options
104
+
data/Rakefile ADDED
@@ -0,0 +1,52 @@
1
+ require 'rake'
2
+
3
+ begin
4
+ require 'jeweler'
5
+ Jeweler::Tasks.new do |s|
6
+ s.name = "has_setting"
7
+ s.summary = %Q{simple setting extension to AR}
8
+ s.email = "info@simplificator.com"
9
+ s.homepage = "http://github.com/simplificator/has_setting"
10
+ s.description = 'Stores settings as key/value pairs in a settings table and provides accessors for them on the owning object'
11
+ s.authors = ["Simplificator GmbH"]
12
+ s.files.exclude '**/*.sqlite3'
13
+ end
14
+ rescue LoadError
15
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
16
+ end
17
+
18
+ require 'rake/rdoctask'
19
+ Rake::RDocTask.new do |rdoc|
20
+ rdoc.rdoc_dir = 'rdoc'
21
+ rdoc.title = 'has_setting'
22
+ rdoc.options << '--line-numbers' << '--inline-source'
23
+ rdoc.rdoc_files.include('README*')
24
+ rdoc.rdoc_files.include('lib/**/*.rb')
25
+ end
26
+
27
+ require 'rake/testtask'
28
+ Rake::TestTask.new(:test) do |t|
29
+ t.libs << 'lib' << 'test'
30
+ t.pattern = 'test/**/*_test.rb'
31
+ t.verbose = false
32
+ end
33
+
34
+ begin
35
+ require 'rcov/rcovtask'
36
+ Rcov::RcovTask.new do |t|
37
+ t.libs << 'test'
38
+ t.test_files = FileList['test/**/*_test.rb']
39
+ t.verbose = true
40
+ end
41
+ rescue LoadError
42
+ puts "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
43
+ end
44
+
45
+ begin
46
+ require 'cucumber/rake/task'
47
+ Cucumber::Rake::Task.new(:features)
48
+ rescue LoadError
49
+ puts "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
50
+ end
51
+
52
+ task :default => :test
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
- :minor: 3
3
- :patch: 9
2
+ :minor: 4
3
+ :patch: 0
4
4
  :major: 0
data/lib/has_setting.rb CHANGED
@@ -14,3 +14,5 @@ HasSetting::Formatters.register_formatter(:float, HasSetting::Formatters::FloatF
14
14
  HasSetting::Formatters.register_formatter(:floats, HasSetting::Formatters::FloatFormatter.new)
15
15
  HasSetting::Formatters.register_formatter(:int, HasSetting::Formatters::IntFormatter.new)
16
16
  HasSetting::Formatters.register_formatter(:ints, HasSetting::Formatters::IntsFormatter.new)
17
+ HasSetting::Formatters.register_formatter(:boolean, HasSetting::Formatters::BooleanFormatter.new)
18
+ HasSetting::Formatters.register_formatter(:booleans, HasSetting::Formatters::BooleanFormatter.new)
@@ -36,13 +36,29 @@ module HasSetting
36
36
 
37
37
  # Formatter for Strings
38
38
  class StringFormatter < NilSafeFormatter
39
- def to_type(value)
39
+ def safe_to_type(value)
40
40
  value
41
41
  end
42
42
  def safe_to_s(value)
43
43
  value.to_s
44
44
  end
45
45
  end
46
+ class BooleanFormatter < NilSafeFormatter
47
+ def safe_to_type(value)
48
+ value == '1'
49
+ end
50
+ def safe_to_s(value)
51
+ value ? '1' : '0'
52
+ end
53
+ end
54
+ class BooleansFormatter < NilSafeFormatter
55
+ def safe_to_type(value)
56
+ value.split(',').map() {|item| Formatters.for_type(:boolean).to_type(item)}
57
+ end
58
+ def safe_to_s(value)
59
+ Array(value).map() {|item| Formatters.for_type(:boolean).to_s(item)}.join(',')
60
+ end
61
+ end
46
62
 
47
63
  class IntsFormatter < NilSafeFormatter
48
64
  def safe_to_type(value)
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/../test_helper'
2
2
  include HasSetting
3
3
  class FormattersTest < Test::Unit::TestCase
4
4
  def test_for_type
5
- [:string, :float, :floats, :int, :ints, :strings].each do |symbol|
5
+ [:string, :float, :floats, :int, :ints, :strings, :boolean, :booleans].each do |symbol|
6
6
  assert(Formatters.for_type(symbol), "No formatter for #{symbol}")
7
7
  end
8
8
  assert_raises(ArgumentError) do
@@ -26,6 +26,7 @@ class FormattersTest < Test::Unit::TestCase
26
26
  assert_equal([',schni,schna,', 'bli', ',bla'], f.to_type('\,schni\,schna\,,bli,\,bla'))
27
27
  assert_equal([',,,,', ',,,', ',,', ','], f.to_type('\,\,\,\,,\,\,\,,\,\,,\,'))
28
28
  end
29
+
29
30
 
30
31
  def test_string_formatter()
31
32
  f = Formatters::StringFormatter.new
@@ -35,6 +36,18 @@ class FormattersTest < Test::Unit::TestCase
35
36
  assert_equal('a', f.to_type('a'))
36
37
  end
37
38
 
39
+ def test_boolean_formatter
40
+ f = Formatters::BooleanFormatter.new
41
+ assert_equal('1', f.to_s(''))
42
+ assert_equal('1', f.to_s(true))
43
+ assert_equal('0', f.to_s(false))
44
+ assert_equal(nil, f.to_s(nil))
45
+
46
+ assert_equal(true, f.to_type('1'))
47
+ assert_equal(false, f.to_type('0'))
48
+ assert_equal(nil, f.to_type(nil))
49
+ end
50
+
38
51
  def test_int_formatter()
39
52
  f = Formatters::IntFormatter.new
40
53
  assert_raises(ArgumentError) do
@@ -107,5 +120,16 @@ class FormattersTest < Test::Unit::TestCase
107
120
  assert_equal([1.2,1.3], f.to_type('1.2,1.3'))
108
121
  assert_equal([1.2,1.3], f.to_type('1.2, 1.3'))
109
122
  end
110
-
123
+ def test_booleans_formatter
124
+ f = Formatters::BooleansFormatter.new
125
+ assert_equal(nil, f.to_s(nil))
126
+ assert_equal('1', f.to_s(true))
127
+ assert_equal('1', f.to_s([true]))
128
+ assert_equal('1,0', f.to_s([true,false]))
129
+
130
+ assert_equal(nil, f.to_type(nil))
131
+ assert_equal([], f.to_type(''))
132
+ assert_equal([true], f.to_type('1'))
133
+ assert_equal([true, false], f.to_type('1,0'))
134
+ end
111
135
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simplificator-has_setting
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.9
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simplificator GmbH
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-02-07 00:00:00 -08:00
12
+ date: 2009-06-30 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -19,28 +19,26 @@ executables: []
19
19
 
20
20
  extensions: []
21
21
 
22
- extra_rdoc_files: []
23
-
22
+ extra_rdoc_files:
23
+ - README
24
24
  files:
25
+ - Rakefile
25
26
  - VERSION.yml
26
- - lib/has_setting
27
+ - lib/has_setting.rb
27
28
  - lib/has_setting/ar_extensions.rb
28
29
  - lib/has_setting/formatters.rb
29
30
  - lib/has_setting/setting.rb
30
- - lib/has_setting.rb
31
31
  - test/bar.rb
32
32
  - test/baz.rb
33
33
  - test/foo.rb
34
34
  - test/test_helper.rb
35
- - test/unit
36
35
  - test/unit/formatters_test.rb
37
36
  - test/unit/has_setting_test.rb
38
- - test/unit/test.sqlite3
37
+ - README
39
38
  has_rdoc: true
40
- homepage: http://github.com/pascalbetz/has_setting
39
+ homepage: http://github.com/simplificator/has_setting
41
40
  post_install_message:
42
41
  rdoc_options:
43
- - --inline-source
44
42
  - --charset=UTF-8
45
43
  require_paths:
46
44
  - lib
@@ -61,7 +59,12 @@ requirements: []
61
59
  rubyforge_project:
62
60
  rubygems_version: 1.2.0
63
61
  signing_key:
64
- specification_version: 2
62
+ specification_version: 3
65
63
  summary: simple setting extension to AR
66
- test_files: []
67
-
64
+ test_files:
65
+ - test/bar.rb
66
+ - test/baz.rb
67
+ - test/foo.rb
68
+ - test/test_helper.rb
69
+ - test/unit/formatters_test.rb
70
+ - test/unit/has_setting_test.rb