acts-as-optionable 0.0.0 → 0.1.1
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 +116 -0
- data/VERSION +1 -1
- data/lib/acts_as_optionable/acts_as_optionable.rb +39 -17
- data/lib/acts_as_optionable/specify_option.rb +12 -1
- data/spec/acts_as_optionable_spec.rb +22 -1
- data/spec/spec.opts +5 -0
- metadata +7 -6
- data/README +0 -13
data/README.rdoc
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
= ActsAsOptionable
|
2
|
+
|
3
|
+
*Warning* I don't recommend using this yet since I'm going to make a couple core changes shortly. Very alpha.
|
4
|
+
|
5
|
+
Support to add options, as well as specify default options, to ActiveRecord models. It's currently a very basic approach, and allows you to fetch options from an ActiveRecord model via an association, or via a hash or object where options are callable as methods. It doesn't support any advanced finder options.
|
6
|
+
|
7
|
+
It works by creating an options table which is polymorphic to ActiveRecord models which call acts_as_optionable.
|
8
|
+
|
9
|
+
The plugin also grants the ability to specify default options for a class, or pass in defaults to an instance at runtime.
|
10
|
+
|
11
|
+
== Installation
|
12
|
+
|
13
|
+
Available as a gem:
|
14
|
+
|
15
|
+
gem install acts-as-optionable
|
16
|
+
|
17
|
+
=== Post Installation
|
18
|
+
|
19
|
+
This creates an Option model in you app.
|
20
|
+
|
21
|
+
1. script/generate option
|
22
|
+
2. Rake db:migrate
|
23
|
+
|
24
|
+
== Usage
|
25
|
+
|
26
|
+
=== Adding options to a model
|
27
|
+
|
28
|
+
class Style < ActiveRecord::Base
|
29
|
+
acts_as_optionable
|
30
|
+
end
|
31
|
+
|
32
|
+
=== Setting, getting, and deleting options
|
33
|
+
|
34
|
+
Use #get_option, #set_option, and #delete_option for interacting with options.
|
35
|
+
|
36
|
+
style = Style.create
|
37
|
+
style.set_option("color", "red")
|
38
|
+
style.get_option("color").value => "red"
|
39
|
+
style.delete_option("color")
|
40
|
+
style.get_option("color") => nil
|
41
|
+
|
42
|
+
|
43
|
+
=== Specifying default options at the class level
|
44
|
+
|
45
|
+
class StyleWithDefaults < ActiveRecord::Base
|
46
|
+
acts_as_optionable
|
47
|
+
|
48
|
+
specify_option :background_color, :default => "white"
|
49
|
+
specify_option :color, :default => "black"
|
50
|
+
end
|
51
|
+
|
52
|
+
style = StyleWithDefaults.create
|
53
|
+
style.get_option("background_color").value => "white"
|
54
|
+
|
55
|
+
=== Specifying instance options at runtime
|
56
|
+
|
57
|
+
style.instance_specified_options = { :foo => {:default => "FOO"} }
|
58
|
+
style.get_option("foo").value => "FOO"
|
59
|
+
|
60
|
+
=== Persisting options specific to a record
|
61
|
+
|
62
|
+
You can persist numeric, boolean, or string values for storage.
|
63
|
+
|
64
|
+
style.set_option("color", "red")
|
65
|
+
style.get_option("color").value => "red"
|
66
|
+
|
67
|
+
style.set_option("active", false)
|
68
|
+
style.get_option("active").value => false
|
69
|
+
|
70
|
+
style.set_option("max_time", 3600)
|
71
|
+
style.get_option("max_time").value => 3600
|
72
|
+
|
73
|
+
=== Option precedence
|
74
|
+
|
75
|
+
Options are preferred in the following order:
|
76
|
+
|
77
|
+
1. Stored options specific for this record
|
78
|
+
2. Runtime options provided to the instance
|
79
|
+
3. Class options specified at load time.
|
80
|
+
|
81
|
+
Example:
|
82
|
+
|
83
|
+
class StyleWithDefaults < ActiveRecord::Base
|
84
|
+
acts_as_optionable
|
85
|
+
|
86
|
+
specify_option :background_color, :default => "white"
|
87
|
+
specify_option :color, :default => "black"
|
88
|
+
end
|
89
|
+
|
90
|
+
style = StyleWithDefaults.create
|
91
|
+
style.instance_specified_options = { :color => { :default => "green" } }
|
92
|
+
style.get_option("background_color").value => "white"
|
93
|
+
style.get_option("color").value => "green"
|
94
|
+
style.set_option("color", "blue")
|
95
|
+
style.get_option("color").value => "blue"
|
96
|
+
|
97
|
+
|
98
|
+
=== Easy options and values retrieval
|
99
|
+
|
100
|
+
Use #options_values_struct to grab a struct to allow for method based calls for all default and set options:
|
101
|
+
|
102
|
+
style = StyleWithDefaults.create
|
103
|
+
options = style.options_values_struct
|
104
|
+
options.color => "black"
|
105
|
+
|
106
|
+
This is useful, for instance, for passing a set of options into a liquid template.
|
107
|
+
|
108
|
+
== TODO
|
109
|
+
|
110
|
+
* Thinking about finding a way to optionally associate the option with an asset table. This would be useful for allowing user defined stylesheet options referencing S3 assets.
|
111
|
+
* Add in a way to return an option value straight away.
|
112
|
+
* Assign multiple settings at a time.
|
113
|
+
|
114
|
+
|
115
|
+
|
116
|
+
Copyright (c) 2010 Brendon Murphy, released under the MIT license
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.1.1
|
@@ -15,6 +15,7 @@ module ActiveRecord
|
|
15
15
|
end
|
16
16
|
|
17
17
|
module IntanceMethods
|
18
|
+
# Store an option persistently and override default option
|
18
19
|
def set_option(name, value)
|
19
20
|
option = get_stored_option(name) || options.build(:name => name.to_s)
|
20
21
|
return if new_option_matches_current?(option)
|
@@ -24,19 +25,13 @@ module ActiveRecord
|
|
24
25
|
ret
|
25
26
|
end
|
26
27
|
|
28
|
+
# Get a stored option, or fall back to a default option
|
27
29
|
def get_option(name)
|
28
30
|
get_stored_option(name) ||
|
29
31
|
get_default_option(name)
|
30
|
-
end
|
31
|
-
|
32
|
-
def get_default_option(name)
|
33
|
-
instance_specified_option(name) || self.class.get_specified_option(name)
|
34
|
-
end
|
35
|
-
|
36
|
-
def get_default_options
|
37
|
-
self.class.optionable_specified_options.merge(instance_specified_options || {})
|
38
|
-
end
|
32
|
+
end
|
39
33
|
|
34
|
+
# Delete a stored option.
|
40
35
|
def delete_option(name)
|
41
36
|
if option = options(:reload).find_by_name(name.to_s)
|
42
37
|
option = option.destroy
|
@@ -46,26 +41,53 @@ module ActiveRecord
|
|
46
41
|
end
|
47
42
|
|
48
43
|
def options_and_defaults
|
49
|
-
options_as_hash = options.inject({}) do |memo, option|
|
50
|
-
memo[option.name.to_s] = option
|
51
|
-
memo
|
52
|
-
end
|
53
44
|
get_default_options.merge(options_as_hash)
|
54
45
|
end
|
55
|
-
|
56
|
-
def specified_options
|
57
|
-
raise "TODO"
|
58
|
-
end
|
59
46
|
|
47
|
+
# Returns an instance of options where option names are callable as methods
|
48
|
+
#
|
49
|
+
# Example:
|
50
|
+
# # Where foo is 'FOO' & bar is 'BAR'
|
51
|
+
# options = foo.options_values_struct
|
52
|
+
# options.foo => "FOO"
|
53
|
+
# options.bar => "BAR"
|
54
|
+
def options_values_struct
|
55
|
+
options = {}
|
56
|
+
options_and_defaults.each do |name, option|
|
57
|
+
options[name.to_s] = option.value
|
58
|
+
end
|
59
|
+
OpenStruct.new(options)
|
60
|
+
end
|
61
|
+
|
60
62
|
protected
|
61
63
|
|
64
|
+
# Gets the default option if set. Prefers instance default over class default.
|
65
|
+
def get_default_option(name)
|
66
|
+
instance_specified_option(name) || self.class.get_specified_option(name)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Get a hash of all default options, with option names as keys.
|
70
|
+
def get_default_options
|
71
|
+
self.class.optionable_specified_options.merge(instance_specified_options || {})
|
72
|
+
end
|
73
|
+
|
74
|
+
# Find the stored option in the database
|
62
75
|
def get_stored_option(name)
|
63
76
|
options.detect { |option| option.name.to_s == name.to_s }
|
64
77
|
end
|
65
78
|
|
79
|
+
# Check if a new value provided is the same as the default option.
|
66
80
|
def new_option_matches_current?(option)
|
67
81
|
(!option.new_record? && option.value == value) || (get_default_option(name).value == value rescue nil)
|
68
82
|
end
|
83
|
+
|
84
|
+
# Return the stored options as a hash, with the option names as keys.
|
85
|
+
def options_as_hash
|
86
|
+
options.inject({}) do |memo, option|
|
87
|
+
memo[option.name.to_s] = option
|
88
|
+
memo
|
89
|
+
end
|
90
|
+
end
|
69
91
|
end
|
70
92
|
end
|
71
93
|
end
|
@@ -3,14 +3,17 @@ module ActiveRecord
|
|
3
3
|
module Optionable
|
4
4
|
module SpecifyOption
|
5
5
|
module ClassMethods
|
6
|
+
# Setup a default value at the class level.
|
6
7
|
def specify_option(option_name, opts = {})
|
7
8
|
optionable_specified_options[option_name.to_s] = Option.new_readonly(:name => option_name.to_s, :default => opts[:default])
|
8
9
|
end
|
9
10
|
|
11
|
+
# Returns a hash of options specified at the class level
|
10
12
|
def optionable_specified_options
|
11
13
|
@optionable_specified_options ||= {}
|
12
14
|
end
|
13
15
|
|
16
|
+
# Get an option specified at the class level.
|
14
17
|
def get_specified_option(option_name)
|
15
18
|
optionable_specified_options[option_name.to_s]
|
16
19
|
end
|
@@ -19,12 +22,20 @@ module ActiveRecord
|
|
19
22
|
module InstanceMethods
|
20
23
|
attr_reader :instance_specified_options
|
21
24
|
|
25
|
+
# Return an option specified for this instance
|
22
26
|
def instance_specified_option(option_name)
|
23
27
|
instance_specified_options[option_name.to_s] if instance_specified_options
|
24
28
|
end
|
25
29
|
|
30
|
+
# Setup instance options. Pass in a hash of options as such:
|
31
|
+
# instance_options = {
|
32
|
+
# :foo => { :default => "FOO" },
|
33
|
+
# :bar => { :default => "BAR" }
|
34
|
+
# }
|
35
|
+
# foo.instance_specified_options = instance_options
|
36
|
+
#
|
37
|
+
# These options only persist in the instance, and aren't stored to database.
|
26
38
|
def instance_specified_options=(opts)
|
27
|
-
opts.symbolize_keys!
|
28
39
|
@instance_specified_options = {}
|
29
40
|
opts.each do |option_name, attributes|
|
30
41
|
attributes.symbolize_keys!
|
@@ -63,7 +63,7 @@ describe "ActsAsOptionable" do
|
|
63
63
|
|
64
64
|
describe "specifying options at class level" do
|
65
65
|
it "should have the proper number of options set" do
|
66
|
-
@optionable.
|
66
|
+
@optionable.options_and_defaults.keys.length.should == 2
|
67
67
|
end
|
68
68
|
|
69
69
|
it "should have the expected options set" do
|
@@ -229,4 +229,25 @@ describe "ActsAsOptionable" do
|
|
229
229
|
end
|
230
230
|
end
|
231
231
|
end
|
232
|
+
|
233
|
+
describe "fetching an object with option names and values" do
|
234
|
+
it "should have a method to fetch option names and values" do
|
235
|
+
lambda { @optionable.options_values_struct }.should_not raise_error(NoMethodError)
|
236
|
+
end
|
237
|
+
|
238
|
+
it "should return an object that lets us retreive values by calling a method named for the option" do
|
239
|
+
option_values = @optionable.options_values_struct
|
240
|
+
option_values.foo.should == "FOOFOO"
|
241
|
+
option_values.bar.should == "BARBAR"
|
242
|
+
end
|
243
|
+
|
244
|
+
it "should contain both set and default options" do
|
245
|
+
@optionable.instance_specified_options = @options_template
|
246
|
+
@optionable.set_option("example_option", 99)
|
247
|
+
option_values = @optionable.options_values_struct
|
248
|
+
option_values.foo.should == "FOOFOO"
|
249
|
+
option_values.fizz.should == "FIZZFIZZ"
|
250
|
+
option_values.example_option.should == 99
|
251
|
+
end
|
252
|
+
end
|
232
253
|
end
|
data/spec/spec.opts
ADDED
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 1
|
8
|
+
- 1
|
9
|
+
version: 0.1.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Brendon Murphy
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-04-
|
17
|
+
date: 2010-04-23 00:00:00 -07:00
|
18
18
|
default_executable:
|
19
19
|
dependencies: []
|
20
20
|
|
@@ -25,10 +25,10 @@ executables: []
|
|
25
25
|
extensions: []
|
26
26
|
|
27
27
|
extra_rdoc_files:
|
28
|
-
- README
|
28
|
+
- README.rdoc
|
29
29
|
files:
|
30
30
|
- MIT-LICENSE
|
31
|
-
- README
|
31
|
+
- README.rdoc
|
32
32
|
- Rakefile
|
33
33
|
- VERSION
|
34
34
|
- lib/acts-as-optionable.rb
|
@@ -38,6 +38,7 @@ files:
|
|
38
38
|
- lib/acts_as_optionable/specify_option.rb
|
39
39
|
- rails/init.rb
|
40
40
|
- spec/acts_as_optionable_spec.rb
|
41
|
+
- spec/spec.opts
|
41
42
|
- spec/spec_helper.rb
|
42
43
|
has_rdoc: true
|
43
44
|
homepage: http://github.com/bemurphy/acts_as_optionable
|
data/README
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
ActsAsOptionable
|
2
|
-
================
|
3
|
-
|
4
|
-
I don't recommend using this yet since I'm going to make a couple core changes shortly. Very alpha.
|
5
|
-
|
6
|
-
|
7
|
-
Example
|
8
|
-
=======
|
9
|
-
|
10
|
-
Example goes here.
|
11
|
-
|
12
|
-
|
13
|
-
Copyright (c) 2010 [name of plugin creator], released under the MIT license
|