hstore_radio_buttons 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +34 -2
- data/lib/hstore_radio_buttons.rb +2 -0
- data/lib/hstore_radio_buttons/button_options.rb +1 -1
- data/lib/hstore_radio_buttons/button_set.rb +28 -11
- data/lib/hstore_radio_buttons/formatter.rb +19 -0
- data/lib/hstore_radio_buttons/helpers/form_helper.rb +7 -5
- data/lib/hstore_radio_buttons/method_namer.rb +24 -0
- data/lib/hstore_radio_buttons/version.rb +1 -1
- data/test/lib/hstore_radio_buttons/button_options_test.rb +0 -12
- data/test/lib/hstore_radio_buttons/button_set_test.rb +14 -29
- data/test/lib/hstore_radio_buttons/helpers/form_builder_test.rb +7 -1
- metadata +61 -19
data/README.md
CHANGED
@@ -152,9 +152,17 @@ To display the radio button set on the form, you have three options:
|
|
152
152
|
<%= form_for @person do |f|>
|
153
153
|
<%= f.hstore_radio_button('gender') %>
|
154
154
|
...
|
155
|
-
<%= f.hstore_radio_button(
|
155
|
+
<%= f.hstore_radio_button(:favorite_barn_animal) %>
|
156
156
|
<% end %>
|
157
157
|
|
158
|
+
You can use the string or a symbolized form. These are synonymous:
|
159
|
+
|
160
|
+
<%= f.hstore_radio_button('gender') %>
|
161
|
+
<%= f.hstore_radio_button(:gender) %>
|
162
|
+
or
|
163
|
+
<%= f.hstore_radio_button('Favorite Barn Animal') %>
|
164
|
+
<%= f.hstore_radio_button(:favorite_barn_animal) %>
|
165
|
+
|
158
166
|
#### Use a helper to display all the radio buttons
|
159
167
|
|
160
168
|
<%= form_for @person do |f|>
|
@@ -167,7 +175,10 @@ To display the radio button set on the form, you have three options:
|
|
167
175
|
<%= f.label(:gender) %>
|
168
176
|
<%= f.radio_button(:gender, 'male') %>
|
169
177
|
<%= f.label(:gender, "Male", :value => 'male') %>
|
170
|
-
...
|
178
|
+
...
|
179
|
+
<%= f.radio_button(:favorite_barn_animal, 'sheep') %>
|
180
|
+
<%= f.label(:favorite_barn_animal, "Sheep", :value => 'sheep') %>
|
181
|
+
...
|
171
182
|
<% end %>
|
172
183
|
|
173
184
|
If you want to avoid the duplication that the above introduces, you can
|
@@ -181,6 +192,15 @@ use the _options method that is added to your model:
|
|
181
192
|
<% end %>
|
182
193
|
<% end %>
|
183
194
|
|
195
|
+
##### Method names when using Rails helpers
|
196
|
+
If you use the Rails helpers, you'll need to use the correct name for
|
197
|
+
the attribute. Use the lowercase, underscored version of your button set
|
198
|
+
name:
|
199
|
+
|
200
|
+
<%= f.radio_button(:favorite_barn_animal, 'sheep') %> #works!
|
201
|
+
<%= f.radio_button('favorite_barn_animal', 'cow') %> #works!
|
202
|
+
<%= f.radio_button('Favorite Barn Animal', 'pig') %> #fail
|
203
|
+
|
184
204
|
### Controlling helper-created output
|
185
205
|
|
186
206
|
By default the `hstore_radio_button` or `hstore_radio_buttons` helpers
|
@@ -223,6 +243,18 @@ buttons as 'selected' when the form is loaded later.
|
|
223
243
|
TODO: It'd be nice to have default values for a set.
|
224
244
|
TODO: Formtastic integration
|
225
245
|
|
246
|
+
### Thanks, etc.
|
247
|
+
|
248
|
+
Many code ideas were 'borrowed' from [Vestal
|
249
|
+
Versions](https://github.com/laserlemon/vestal_versions/) and [LRD]
|
250
|
+
(https://github.com/LRDesign). Testing and design ideas were also
|
251
|
+
contributed by [Davin Lagerroos](https://github.com/davinlagerroos).
|
252
|
+
|
253
|
+
### Versions
|
254
|
+
|
255
|
+
0.0.2 - Fixes to inconsistency in how you call buttons by name.
|
256
|
+
0.0.1 - Initial
|
257
|
+
|
226
258
|
## Contributing
|
227
259
|
|
228
260
|
1. Fork it
|
data/lib/hstore_radio_buttons.rb
CHANGED
@@ -6,6 +6,8 @@ require 'hstore_radio_buttons/version'
|
|
6
6
|
require 'hstore_radio_buttons/configuration'
|
7
7
|
require 'hstore_radio_buttons/button_options'
|
8
8
|
require 'hstore_radio_buttons/button_set'
|
9
|
+
require 'hstore_radio_buttons/method_namer'
|
10
|
+
require 'hstore_radio_buttons/formatter'
|
9
11
|
require 'hstore_radio_buttons/helpers/form_helper'
|
10
12
|
|
11
13
|
module HstoreRadioButtons
|
@@ -1,32 +1,49 @@
|
|
1
1
|
module HstoreRadioButtons
|
2
2
|
class ButtonSet
|
3
3
|
def initialize(button_definition, model)
|
4
|
-
|
5
|
-
getter_method = button_definition.name.to_sym
|
6
|
-
options_method = "#{button_definition.name}_options".to_sym
|
4
|
+
namer = HstoreRadioButtons::MethodNamer.new(button_definition.name)
|
7
5
|
|
8
|
-
|
6
|
+
create_instance_methods(button_definition, model, namer)
|
7
|
+
create_getters_on_class(model, namer)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def create_instance_methods(button_definition, model, namer)
|
13
|
+
create_getter(button_definition, model, namer)
|
14
|
+
create_setter(button_definition, model, namer)
|
15
|
+
create_options(button_definition, model, namer)
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_getter(button_definition, model, namer)
|
19
|
+
model.send(:define_method, namer.getter) {
|
9
20
|
hstore_data_proxy[button_definition.name]
|
10
21
|
}
|
22
|
+
end
|
11
23
|
|
12
|
-
|
13
|
-
|
24
|
+
def create_setter(button_definition, model, namer)
|
25
|
+
model.send(:define_method, namer.setter) {|value|
|
26
|
+
if self.send(namer.options).include?(value)
|
14
27
|
hstore_data_proxy[button_definition.name] = value
|
15
28
|
else
|
16
29
|
hstore_data_proxy[button_definition.name] = nil
|
17
30
|
end
|
18
31
|
}
|
32
|
+
end
|
19
33
|
|
20
|
-
|
34
|
+
def create_options(button_definition, model, namer)
|
35
|
+
model.send(:define_method, namer.options) {
|
21
36
|
button_definition.options
|
22
37
|
}
|
38
|
+
end
|
23
39
|
|
24
|
-
|
25
|
-
|
40
|
+
def create_getters_on_class(model, namer)
|
41
|
+
if !model.instance_variable_defined?(:@hstore_button_getters)
|
42
|
+
model.instance_variable_set(:@hstore_button_getters, Set.new)
|
26
43
|
end
|
27
|
-
all_buttons_on_model = model.send(:instance_variable_get, :@
|
44
|
+
all_buttons_on_model = model.send(:instance_variable_get, :@hstore_button_getters)
|
28
45
|
|
29
|
-
model.send(:instance_variable_set, :@
|
46
|
+
model.send(:instance_variable_set, :@hstore_button_getters, all_buttons_on_model << namer.getter)
|
30
47
|
end
|
31
48
|
end
|
32
49
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module HstoreRadioButtons
|
2
|
+
class Formatter
|
3
|
+
def initialize(raw_button_name)
|
4
|
+
self.raw_button_name = raw_button_name
|
5
|
+
end
|
6
|
+
|
7
|
+
def to_method
|
8
|
+
raw_button_name.to_s.gsub(/ /,"_").downcase
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_title
|
12
|
+
raw_button_name.to_s.gsub(/_/," ").titleize
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
attr_accessor :raw_button_name
|
18
|
+
end
|
19
|
+
end
|
@@ -14,17 +14,19 @@ module HstoreRadioButtons::FormBuilder
|
|
14
14
|
|
15
15
|
def hstore_radio_button(method, options = {})
|
16
16
|
options[:separator] = (options[:separator] ? options[:separator] : "<br />")
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
methods = HstoreRadioButtons::MethodNamer.new(method)
|
18
|
+
|
19
|
+
button_set = "#{HstoreRadioButtons::Formatter.new(method).to_title}#{options[:separator]}"
|
20
|
+
|
21
|
+
object.public_send(methods.options).each do |radio_option|
|
22
|
+
button_set += @template.hstore_radio_button(@object_name, methods.getter, radio_option, objectify_options(options))
|
21
23
|
end
|
22
24
|
content_tag(:div, button_set.html_safe).html_safe
|
23
25
|
end
|
24
26
|
|
25
27
|
def hstore_radio_buttons(options = {})
|
26
28
|
all_buttons = ""
|
27
|
-
object.class.instance_variable_get(:@
|
29
|
+
object.class.instance_variable_get(:@hstore_button_getters).each do |method|
|
28
30
|
all_buttons += hstore_radio_button(method, options)
|
29
31
|
end
|
30
32
|
all_buttons.html_safe
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module HstoreRadioButtons
|
2
|
+
class MethodNamer
|
3
|
+
def initialize(button_name)
|
4
|
+
self.button_name = HstoreRadioButtons::Formatter.new(button_name).to_method
|
5
|
+
end
|
6
|
+
|
7
|
+
def setter
|
8
|
+
"#{button_name}=".to_sym
|
9
|
+
end
|
10
|
+
|
11
|
+
def getter
|
12
|
+
button_name.to_sym
|
13
|
+
end
|
14
|
+
|
15
|
+
def options
|
16
|
+
"#{button_name}_options".to_sym
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
attr_accessor :button_name
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -1,18 +1,6 @@
|
|
1
1
|
require_relative '../../test_helper.rb'
|
2
2
|
|
3
3
|
describe HstoreRadioButtons::ButtonOptions do
|
4
|
-
describe "#name" do
|
5
|
-
it "replaces spaces in a name with underscores" do
|
6
|
-
it = HstoreRadioButtons::ButtonOptions.new('test name', nil)
|
7
|
-
it.name.must_equal 'test_name'
|
8
|
-
end
|
9
|
-
|
10
|
-
it "downcases the name" do
|
11
|
-
it = HstoreRadioButtons::ButtonOptions.new('Test', nil)
|
12
|
-
it.name.must_equal 'test'
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
4
|
describe "#options" do
|
17
5
|
it "turns a single option into an array" do
|
18
6
|
it = HstoreRadioButtons::ButtonOptions.new('test', 1)
|
@@ -3,56 +3,41 @@ require_relative '../../test_helper.rb'
|
|
3
3
|
describe HstoreRadioButtons::ButtonSet do
|
4
4
|
describe '#initialize' do
|
5
5
|
before :each do
|
6
|
-
@test_yaml_file_location = './test/support/config/hstore_radio_button_sets.yml'
|
7
6
|
@it = Person.new
|
8
|
-
|
9
|
-
@
|
10
|
-
@
|
11
|
-
|
12
|
-
@raw_button_definitions.each do |button_definition|
|
13
|
-
button_options = HstoreRadioButtons::ButtonOptions.new(button_definition[0],button_definition[1])
|
14
|
-
@button_definitions << button_options
|
15
|
-
HstoreRadioButtons::ButtonSet.new(button_options,@it.class)
|
16
|
-
end
|
7
|
+
@button_definition = OpenStruct.new({name: 'test name', options: [1,2,3]})
|
8
|
+
HstoreRadioButtons::ButtonSet.new(@button_definition,@it.class)
|
9
|
+
@method_names = HstoreRadioButtons::MethodNamer.new(@button_definition.name)
|
17
10
|
end
|
18
11
|
|
19
12
|
it 'adds getters and setters for the button sets defined in the config file' do
|
20
|
-
@
|
21
|
-
|
22
|
-
@it.must_respond_to "#{button_definition.name}=".to_sym
|
23
|
-
end
|
13
|
+
@it.must_respond_to @method_names.getter
|
14
|
+
@it.must_respond_to @method_names.setter
|
24
15
|
end
|
25
16
|
|
26
17
|
it "adds a method that returns the button set's options" do
|
27
|
-
@
|
28
|
-
|
29
|
-
@it.send("#{button_definition.name}_options".to_sym).must_equal button_definition.options
|
30
|
-
end
|
18
|
+
@it.must_respond_to @method_names.options
|
19
|
+
@it.send(@method_names.options).must_equal @button_definition.options
|
31
20
|
end
|
32
21
|
|
33
22
|
it "defines the setter so that a value not in the set's option is not passed to the hstore" do
|
34
23
|
bad_value = "hackery_nonsense"
|
35
|
-
@
|
36
|
-
|
37
|
-
@it.send(button_definition.name.to_sym).must_be_nil
|
38
|
-
end
|
24
|
+
@it.send(@method_names.setter, bad_value)
|
25
|
+
@it.send(@method_names.getter).must_be_nil
|
39
26
|
end
|
40
27
|
|
41
28
|
it 'persists data sent to setters' do
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
@it.send(button_definition.name.to_sym).must_equal random_value
|
46
|
-
end
|
29
|
+
random_value = @button_definition.options.sample
|
30
|
+
@it.send(@method_names.setter, random_value)
|
31
|
+
@it.send(@method_names.getter).must_equal random_value
|
47
32
|
end
|
48
33
|
|
49
34
|
it 'allows the use of ActiveModel validation methods' do
|
50
|
-
@it.class.validates_presence_of(@
|
35
|
+
@it.class.validates_presence_of(@method_names.getter)
|
51
36
|
@it.valid?.must_equal false
|
52
37
|
end
|
53
38
|
|
54
39
|
it 'creates a class instance variable that returns the names of all hstore button names' do
|
55
|
-
@it.class.instance_variable_get(:@
|
40
|
+
@it.class.instance_variable_get(:@hstore_button_getters).must_include :test_name
|
56
41
|
end
|
57
42
|
end
|
58
43
|
end
|
@@ -18,6 +18,12 @@ class FormBuilderTest < ActionView::TestCase
|
|
18
18
|
assert it.respond_to?(:hstore_radio_button)
|
19
19
|
end
|
20
20
|
|
21
|
+
test "#hstore_radio_button responds to both symbolized and string forms of button-set names" do
|
22
|
+
it = ActionView::Helpers::FormBuilder.new(:person, @person_instance, view, {}, proc {})
|
23
|
+
assert_equal it.hstore_radio_button(:gender), it.hstore_radio_button('gender')
|
24
|
+
assert_equal it.hstore_radio_button(:favorite_barn_animal), it.hstore_radio_button('Favorite Barn Animal')
|
25
|
+
end
|
26
|
+
|
21
27
|
test "FormBuilder#hstore_radio_button wraps the whole thing in a div" do
|
22
28
|
view.stubs(:hstore_radio_button).with(any_parameters).returns("")
|
23
29
|
it = ActionView::Helpers::FormBuilder.new(:person, @person_instance, view, {}, proc {})
|
@@ -53,7 +59,7 @@ class FormBuilderTest < ActionView::TestCase
|
|
53
59
|
test "#hstore_radio_buttons builds a button set for each button defined in the class" do
|
54
60
|
it = ActionView::Helpers::FormBuilder.new(:person, @person_instance, view, {}, proc {})
|
55
61
|
|
56
|
-
all_buttons = Person.instance_variable_get(:@
|
62
|
+
all_buttons = Person.instance_variable_get(:@hstore_button_getters)
|
57
63
|
expected = ""
|
58
64
|
all_buttons.each do |b|
|
59
65
|
expected += it.hstore_radio_button(b)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hstore_radio_buttons
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
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: 2013-06-
|
12
|
+
date: 2013-06-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,15 @@ dependencies:
|
|
21
21
|
version: '3.0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3.0'
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: activesupport
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ~>
|
@@ -32,10 +37,15 @@ dependencies:
|
|
32
37
|
version: '3.0'
|
33
38
|
type: :runtime
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '3.0'
|
36
46
|
- !ruby/object:Gem::Dependency
|
37
47
|
name: actionpack
|
38
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
39
49
|
none: false
|
40
50
|
requirements:
|
41
51
|
- - ~>
|
@@ -43,10 +53,15 @@ dependencies:
|
|
43
53
|
version: '3.0'
|
44
54
|
type: :runtime
|
45
55
|
prerelease: false
|
46
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
47
62
|
- !ruby/object:Gem::Dependency
|
48
63
|
name: activerecord-postgres-hstore
|
49
|
-
requirement:
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
50
65
|
none: false
|
51
66
|
requirements:
|
52
67
|
- - ! '>='
|
@@ -54,10 +69,15 @@ dependencies:
|
|
54
69
|
version: '0'
|
55
70
|
type: :runtime
|
56
71
|
prerelease: false
|
57
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
58
78
|
- !ruby/object:Gem::Dependency
|
59
79
|
name: bundler
|
60
|
-
requirement:
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
61
81
|
none: false
|
62
82
|
requirements:
|
63
83
|
- - ~>
|
@@ -65,10 +85,15 @@ dependencies:
|
|
65
85
|
version: '1.3'
|
66
86
|
type: :development
|
67
87
|
prerelease: false
|
68
|
-
version_requirements:
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '1.3'
|
69
94
|
- !ruby/object:Gem::Dependency
|
70
95
|
name: rake
|
71
|
-
requirement:
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
72
97
|
none: false
|
73
98
|
requirements:
|
74
99
|
- - ! '>='
|
@@ -76,10 +101,15 @@ dependencies:
|
|
76
101
|
version: '0'
|
77
102
|
type: :development
|
78
103
|
prerelease: false
|
79
|
-
version_requirements:
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
80
110
|
- !ruby/object:Gem::Dependency
|
81
111
|
name: sqlite3
|
82
|
-
requirement:
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
83
113
|
none: false
|
84
114
|
requirements:
|
85
115
|
- - ! '>='
|
@@ -87,10 +117,15 @@ dependencies:
|
|
87
117
|
version: '0'
|
88
118
|
type: :development
|
89
119
|
prerelease: false
|
90
|
-
version_requirements:
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
91
126
|
- !ruby/object:Gem::Dependency
|
92
127
|
name: mocha
|
93
|
-
requirement:
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
94
129
|
none: false
|
95
130
|
requirements:
|
96
131
|
- - ! '>='
|
@@ -98,7 +133,12 @@ dependencies:
|
|
98
133
|
version: '0'
|
99
134
|
type: :development
|
100
135
|
prerelease: false
|
101
|
-
version_requirements:
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
102
142
|
description: Works with postgres's hstore data type and Rails to let you display/store
|
103
143
|
a collection of radio buttons in an hstore field
|
104
144
|
email:
|
@@ -120,8 +160,10 @@ files:
|
|
120
160
|
- lib/hstore_radio_buttons/button_options.rb
|
121
161
|
- lib/hstore_radio_buttons/button_set.rb
|
122
162
|
- lib/hstore_radio_buttons/configuration.rb
|
163
|
+
- lib/hstore_radio_buttons/formatter.rb
|
123
164
|
- lib/hstore_radio_buttons/helpers/form_helper.rb
|
124
165
|
- lib/hstore_radio_buttons/hstore_radio_data.rb
|
166
|
+
- lib/hstore_radio_buttons/method_namer.rb
|
125
167
|
- lib/hstore_radio_buttons/version.rb
|
126
168
|
- test/lib/hstore_radio_buttons/button_options_test.rb
|
127
169
|
- test/lib/hstore_radio_buttons/button_set_test.rb
|
@@ -155,7 +197,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
155
197
|
version: '0'
|
156
198
|
requirements: []
|
157
199
|
rubyforge_project:
|
158
|
-
rubygems_version: 1.8.
|
200
|
+
rubygems_version: 1.8.25
|
159
201
|
signing_key:
|
160
202
|
specification_version: 3
|
161
203
|
summary: Define a set of radio buttons for a model and then save the perisisted data
|