formtastic_tristate_radio 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/README.md +57 -26
- data/app/inputs/tristate_radio_input.rb +57 -116
- data/app/models/active_record/base.rb +5 -1
- data/config/initializers/activemodel_type_boolean.rb +1 -1
- data/lib/formtastic_tristate_radio/engine.rb +7 -0
- data/lib/formtastic_tristate_radio/version.rb +3 -1
- data/lib/formtastic_tristate_radio.rb +5 -4
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c61035dc61996da98086ef61f099baa1552221ccbae23e7f67a7d430494f400f
|
4
|
+
data.tar.gz: 870da0885677bfe7e1ccfbf02cf7b3c0c1b6803c01de4167dfd4f7cda3c5fa16
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c36a9fe479ada5422ccfaf5feed00da1d9efaeeea737779bf9cfc87826ecd16864780f1c70f47d7ecb4854040bf5ef751e51aae24abd8381afaa82cfc1a1cf2a
|
7
|
+
data.tar.gz: b6952ce6cc1b434103f4f0abe58a6e7b8fe5d96d0691afd5275fa61c37635bcf420f18511e7bbdf6ecf7de3825d2b8416dc8e071557be5d67b51b4a9571e91f6
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
## [0.2.0] - 2021-11-04
|
4
|
+
|
5
|
+
- Custom translation override from form via options
|
6
|
+
- Custom error class
|
7
|
+
- YARD documentation for everything
|
8
|
+
- Inherits from `Formtastic::Inputs::RadioInput` and patches only necessary methods
|
9
|
+
- Error YAML example for ActiveAdmin included only if ActiveAdmin is detected
|
10
|
+
|
11
|
+
## [0.1.0] - 2021-11-01
|
12
|
+
|
13
|
+
Initial release
|
data/README.md
CHANGED
@@ -1,50 +1,63 @@
|
|
1
1
|
# Formtastic tri-state radio
|
2
2
|
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/formtastic_tristate_radio.svg)](https://badge.fury.io/rb/formtastic_tristate_radio)
|
4
|
+
|
3
5
|
## What is “tri-state”?
|
4
6
|
|
5
|
-
— that which has 3
|
7
|
+
— that which has 3 states.
|
6
8
|
|
7
|
-
By defenition Boolean values have 2
|
9
|
+
By defenition Boolean values have 2 states: True & False.
|
8
10
|
|
9
|
-
However, if
|
11
|
+
However, if you store a Boolean value in a database column with no `NOT NULL` restriction, it aquires a 3<sup>d</sup> possible state: `null`.
|
10
12
|
|
11
|
-
Some may
|
13
|
+
Some may consider this practice questionable — I don’t think so. In real life you always have a case when the answer to your question may be only “yes” or “no”, but you don’t know the answer yet. Using a string type column, storing there `"yes"`, `"no"` and `"unset"` + using a state machine + validations — feels overkill to me.
|
12
14
|
|
13
15
|
|
14
16
|
## What the gem does
|
15
17
|
|
16
|
-
1. Provides a
|
17
|
-
1. Teaches Rails recognize `"null"` and `"nil"` param values as
|
18
|
-
1. Encourages you to
|
18
|
+
1. Provides a custom Formtastic input type `:tristate_radio` which renders 3 radios (“Yes”, “No”, “Unset”) instead of a checkbox (only where you put it).
|
19
|
+
1. Teaches Rails recognize `"null"` and `"nil"` param values as `nil`. See “[How it works](#how-it-works)” ☟ section for technical details on this.
|
20
|
+
1. Encourages you to add translations for ActiveAdmin “status tag” so that `nil` be correctly translated as “Unset” instead of “False”.
|
19
21
|
|
20
22
|
|
21
23
|
## Usage
|
22
24
|
|
23
|
-
For a
|
25
|
+
For a Boolean column with 3 possible states:
|
24
26
|
|
25
27
|
```ruby
|
26
|
-
f.input :
|
28
|
+
f.input :am_i_awake, as: :tristate_radio
|
29
|
+
f.input :is_this_a_dream, as: :tristate_radio, null: "Reality is a persistent hallucination"
|
27
30
|
```
|
28
31
|
|
29
|
-
You get (HTML is simplified):
|
32
|
+
You get (HTML is simplified, actually there are more classes etc.):
|
30
33
|
|
31
34
|
```html
|
32
35
|
<fieldset>
|
33
|
-
<
|
34
|
-
<input name="
|
35
|
-
<input name="
|
36
|
+
<legend>Am i awake?</legend>
|
37
|
+
<input name="am_i_awake" type="radio" value="true"> <label>Yes</label>
|
38
|
+
<input name="am_i_awake" type="radio" value="false"> <label>No</label>
|
39
|
+
<input name="am_i_awake" type="radio" value="null"> <label>Unset</label>
|
36
40
|
</fieldset>
|
37
|
-
```
|
38
41
|
|
39
|
-
|
42
|
+
<fieldset>
|
43
|
+
<legend>Is this a dream?</legend>
|
44
|
+
<input name="is_this_a_dream" type="radio" value="true"> <label>Yes</label>
|
45
|
+
<input name="is_this_a_dream" type="radio" value="false"> <label>No</label>
|
46
|
+
<input name="is_this_a_dream" type="radio" value="null"> <label>Reality is a persistent hallucination</label>
|
47
|
+
</fieldset>
|
48
|
+
```
|
40
49
|
|
41
50
|
|
42
51
|
## Installation
|
43
52
|
|
53
|
+
### Gem
|
54
|
+
|
44
55
|
```ruby
|
45
56
|
gem "formtastic_tristate_radio"
|
46
57
|
```
|
47
58
|
|
59
|
+
### Translations
|
60
|
+
|
48
61
|
Add translation for the new “unset” option:
|
49
62
|
|
50
63
|
```yaml
|
@@ -55,7 +68,15 @@ ru:
|
|
55
68
|
null: Неизвестно # <- this you must provide youself
|
56
69
|
```
|
57
70
|
|
58
|
-
|
71
|
+
As noted in [Usage](#usage), you can override individual translations like so:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
f.input :attribute, as: :tristate_radio, null: "Your text"
|
75
|
+
```
|
76
|
+
|
77
|
+
### ActiveAdmin translations
|
78
|
+
|
79
|
+
ActiveAdmin will automatically translate `nil` as “No”, so if you use ActiveAdmin, add translation like so:
|
59
80
|
|
60
81
|
```yaml
|
61
82
|
ru:
|
@@ -63,23 +84,25 @@ ru:
|
|
63
84
|
status_tag:
|
64
85
|
:yes: Да
|
65
86
|
:no: Нет
|
66
|
-
|
87
|
+
unset: Неизвестно
|
67
88
|
```
|
68
89
|
|
90
|
+
Notice that the key ActiveAdmin uses is “unset”, not “null”.
|
91
|
+
|
69
92
|
|
70
93
|
## Configuration
|
71
94
|
|
72
|
-
Nothing is configurable yet. I think of
|
95
|
+
Nothing is configurable yet. I think of making configurable which values are regognized as `nil`.
|
73
96
|
|
74
97
|
|
75
98
|
## Dependencies
|
76
99
|
|
77
|
-
Now the gem depends on
|
100
|
+
Now the gem depends on [Formtastic](https://github.com/formtastic/formtastic) (naturally) and Rails. Frankly I am not sure whether I will have time to make it work with other frameworks.
|
78
101
|
|
79
102
|
|
80
103
|
## How it works
|
81
104
|
|
82
|
-
In Ruby any String is cast to
|
105
|
+
In Ruby any String is cast to `true`:
|
83
106
|
|
84
107
|
```ruby
|
85
108
|
!!"" #=> true
|
@@ -89,11 +112,11 @@ In Ruby any String is cast to `true`:
|
|
89
112
|
!!"null" #=> true
|
90
113
|
```
|
91
114
|
|
92
|
-
Web form params are passed as
|
115
|
+
Web form params are passed as plain text and are interpreted as String by Rack.
|
93
116
|
|
94
|
-
So how Boolean values are transfered as
|
117
|
+
So how Boolean values are transfered as strings if a `"no"` or `"0"` and even `""` is truthy in Ruby?
|
95
118
|
|
96
|
-
Frameworks just have a
|
119
|
+
Frameworks just have a list of string values to be recognized and mapped to Boolean values:
|
97
120
|
|
98
121
|
```ruby
|
99
122
|
ActiveModel::Type::Boolean::FALSE_VALUES
|
@@ -115,7 +138,7 @@ ActiveModel::Type::Boolean.new.cast("off") #=> false
|
|
115
138
|
# etc
|
116
139
|
```
|
117
140
|
|
118
|
-
So what [I do in
|
141
|
+
So what [I do in this gem](https://github.com/sergeypedan/formtastic_tristate_radio/blob/master/config/initializers/activemodel_type_boolean.rb) is extend `ActiveModel::Type::Boolean` in a consistent way to teach it recognize null-ish values as `nil`:
|
119
142
|
|
120
143
|
```ruby
|
121
144
|
module ActiveModel
|
@@ -143,9 +166,17 @@ ActiveModel::Type::Boolean.new.cast("nil") #=> nil
|
|
143
166
|
ActiveModel::Type::Boolean.new.cast(:nil) #=> nil
|
144
167
|
```
|
145
168
|
|
146
|
-
**Warning**: as
|
169
|
+
**Warning**: as you might have noticed, default Rails behavior is changed. If you rely on Rails’ automatic conversion of strings with value `"null"` into `true`, this gem might not be for you (and you are definitely doing something weird).
|
170
|
+
|
171
|
+
|
172
|
+
## Roadmap
|
173
|
+
|
174
|
+
- [ ] Load translations from gem
|
175
|
+
- [ ] Add translations into most popular languages
|
176
|
+
- [ ] Rgister `:tristate_radio` for Boolean columns with `null`
|
177
|
+
- [ ] Decouple from Rails
|
147
178
|
|
148
179
|
|
149
180
|
## License
|
150
181
|
|
151
|
-
The gem is available as
|
182
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -3,168 +3,109 @@
|
|
3
3
|
require "formtastic"
|
4
4
|
|
5
5
|
# It may also be appropriate to put this file in `app/inputs`
|
6
|
-
class TristateRadioInput
|
6
|
+
class TristateRadioInput < Formtastic::Inputs::RadioInput
|
7
7
|
|
8
|
-
|
9
|
-
include Formtastic::Inputs::Base::Collections
|
10
|
-
include Formtastic::Inputs::Base::Choices
|
11
|
-
|
12
|
-
|
13
|
-
# UNSET_KEY = :null
|
14
|
-
UNSET_KEY = ActiveModel::Type::Boolean::NULL_VALUES.reject(&:blank?).first
|
8
|
+
# No equals `:null`.
|
15
9
|
#
|
16
|
-
# Mind ActiveAdmin status resolving logic:
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
|
21
|
-
MISSING_TRANSLATION_ERROR_MSG = <<~HEREDOC
|
22
|
-
|
10
|
+
# Mind ActiveAdmin [status resolving logic](https://github.com/activeadmin/activeadmin/blob/master/lib/active_admin/views/components/status_tag.rb#L51):
|
11
|
+
# in status tag builder the value is lowercased before casting into Boolean, and the keyword for nil is `"unset"`.
|
12
|
+
# So if we have lowercase `"unset"`, translations from `ru.formtastic.unset` will be overriden by `ru.active_admin.status_tag.unset`.
|
13
|
+
#
|
14
|
+
UNSET_KEY = ActiveModel::Type::Boolean::NULL_VALUES.reject(&:blank?).first
|
23
15
|
|
24
|
-
|
16
|
+
I18N_EXAMPLE_ACTIVEADMIN = <<~YAML.chomp
|
25
17
|
ru:
|
26
18
|
active_admin:
|
27
19
|
status_tag:
|
28
20
|
:yes: Да
|
29
21
|
:no: Нет
|
30
22
|
:#{UNSET_KEY}: Неизвестно
|
23
|
+
YAML
|
31
24
|
|
32
|
-
|
25
|
+
I18N_EXAMPLE_FORMTASTIC = <<~YAML.chomp
|
33
26
|
ru:
|
34
27
|
formtastic:
|
35
28
|
:yes: Да
|
36
29
|
:no: Нет
|
37
30
|
:#{UNSET_KEY}: Неизвестно
|
38
|
-
|
39
|
-
Note: “yes”, “no”, “null” and some other words are reserved, converted into Boolean values in YAML, so you need to quote or symbolize them.
|
40
|
-
HEREDOC
|
31
|
+
YAML
|
41
32
|
|
42
33
|
|
43
|
-
#
|
34
|
+
# @note In you have ActiveAdmin installed, it will give you YAML example for ActiveAdmin as well, otherwise only for Formtastic
|
44
35
|
#
|
45
|
-
# @
|
36
|
+
# @return [String] error message with YAML examples for the “unset” label translation lookup error
|
46
37
|
#
|
47
|
-
def
|
48
|
-
|
38
|
+
def self.missing_i18n_error_msg
|
39
|
+
msg = []
|
40
|
+
msg << "Add translations for the “unset” radio label"
|
41
|
+
msg << ["For radiobutton labels in forms:", I18N_EXAMPLE_FORMTASTIC].join("\n")
|
42
|
+
msg << "Note: “yes”, “no” and some other reserved words are converted into Boolean values in YAML, so you need to quote or symbolize them."
|
43
|
+
msg << ["For ActiveAdmin status tags in index & view tables:", I18N_EXAMPLE_ACTIVEADMIN].join("\n") if !!defined?(ActiveAdmin)
|
44
|
+
msg.join("\n\n")
|
49
45
|
end
|
50
46
|
|
51
47
|
|
52
|
-
#
|
48
|
+
# @see https://github.com/formtastic/formtastic/blob/35dc806964403cb2bb0a6074b951ceef906c8581/lib/formtastic/inputs/base/choices.rb#L59 Original Formtastic method
|
53
49
|
#
|
54
|
-
# @return [
|
50
|
+
# @return [Hash] HTML options for the `<input type="radio" />` tag
|
55
51
|
#
|
56
|
-
|
57
|
-
|
52
|
+
# Adds `{ selected: true }` to the original options Hash if the choice value equals attribute value (to ultimately set for `checked="checked"`)
|
53
|
+
#
|
54
|
+
def choice_html_options(choice)
|
55
|
+
super.merge({ checked: selected?(choice) })
|
58
56
|
end
|
59
57
|
|
60
58
|
|
61
|
-
#
|
62
|
-
#
|
59
|
+
# @example Original method
|
60
|
+
# def collection_for_boolean
|
61
|
+
# true_text = options[:true] || Formtastic::I18n.t(:yes)
|
62
|
+
# false_text = options[:false] || Formtastic::I18n.t(:no)
|
63
|
+
# [ [true_text, true], [false_text, false] ]
|
64
|
+
# end
|
63
65
|
#
|
64
|
-
#
|
65
|
-
# { for: nil, class: ["label"] }
|
66
|
+
# collection_for_boolean #=> [["Да", true], ["Нет", false]]
|
66
67
|
#
|
67
|
-
|
68
|
-
|
69
|
-
end
|
70
|
-
|
71
|
-
|
72
|
-
# choice_value(choice) => true | false | UNSET_KEY <- in our version
|
73
|
-
# choice_value(choice) => true | false | ? <- in regular radio-buttons version
|
74
|
-
# method => :status
|
75
|
-
# object => ActiveRecord::Base model subclass, `User`
|
68
|
+
# @example This patched method
|
69
|
+
# collection_for_boolean #=> [["Да", true], ["Нет", false], ["Неизвестно", :null]]
|
76
70
|
#
|
77
|
-
# @
|
71
|
+
# @return [Array<[String, (Boolean|String|Symbol)]>] an array of “choices”, each presented as an array with 2 items: HTML label text and HTML input value
|
78
72
|
#
|
79
|
-
#
|
73
|
+
# @see https://github.com/formtastic/formtastic/blob/e34baba470d2fda75bf9748cff8898ee0ed29075/lib/formtastic/inputs/base/collections.rb#L131 Original Formtastic method
|
80
74
|
#
|
81
|
-
def
|
82
|
-
|
75
|
+
def collection_for_boolean
|
76
|
+
super + [[label_text_for_unset, UNSET_KEY]]
|
83
77
|
end
|
84
78
|
|
85
79
|
|
86
|
-
#
|
87
|
-
# "<input ...> Text..."
|
80
|
+
# Checks translation passed as option, then checks in locale
|
88
81
|
#
|
89
|
-
# @
|
90
|
-
#
|
91
|
-
# input_html_options => { id: "task_status", required: false, autofocus: false, readonly: false}
|
82
|
+
# @example
|
83
|
+
# label_text_for_unset #=> "Неизвестно"
|
92
84
|
#
|
93
|
-
#
|
94
|
-
# => { id: "task_status_completed", required: false, autofocus: false, readonly: false }
|
85
|
+
# @return [String] Label of the radio that stands for the unknown choice
|
95
86
|
#
|
96
|
-
#
|
97
|
-
#
|
98
|
-
# choice_html_options(choice) => { id: "task_status_completed" }
|
99
|
-
# choice_value(choice) => "completed"
|
100
|
-
# input_name => :status
|
87
|
+
# @raise [StandardError] if the translation could not be found
|
88
|
+
# @see missing_i18n_error_msg
|
101
89
|
#
|
102
|
-
def
|
103
|
-
|
104
|
-
|
105
|
-
choice_value(choice),
|
106
|
-
input_html_options.merge(choice_html_options(choice)).merge({ required: false, checked: selected?(choice) })
|
107
|
-
) << choice_label(choice)
|
90
|
+
def label_text_for_unset
|
91
|
+
options.fetch(:null, Formtastic::I18n.t(UNSET_KEY)).presence or \
|
92
|
+
fail FormtasticTristateRadio::MissingTranslationError.new(self.class.missing_i18n_error_msg)
|
108
93
|
end
|
109
94
|
|
110
95
|
|
111
|
-
#
|
112
|
-
#
|
113
|
-
#
|
114
|
-
#
|
96
|
+
# @example For each item of `collection` it runs:
|
97
|
+
# selected?(["Да", true]) #=> false
|
98
|
+
# selected?(["Нет", false]) #=> false
|
99
|
+
# selected?(["Неизвестно", :null]) #=> true
|
115
100
|
#
|
116
|
-
|
117
|
-
label_html_options.merge({ for: choice_input_dom_id(choice), class: nil })
|
118
|
-
end
|
119
|
-
|
120
|
-
|
121
|
-
# choice_wrapping_html_options(choice) #=> { class: "choice" }
|
101
|
+
# @param choice [Array<[String, (Boolean|String|Symbol)]>]
|
122
102
|
#
|
123
|
-
#
|
124
|
-
# <label>Status</label>
|
125
|
-
# </legend>"
|
103
|
+
# @return [Boolean] answer to the question “Is the passed option selected?”
|
126
104
|
#
|
127
|
-
#
|
128
|
-
# <input type="radio" value="completed" name="task[status]" /> Completed
|
129
|
-
# </label>"
|
105
|
+
# @note For this to work, `ActiveModel::Type::Boolean` must be patched to resolve `UNSET_KEY` as `nil`.
|
130
106
|
#
|
131
|
-
|
132
|
-
|
133
|
-
# choice_html(choice)
|
134
|
-
# end
|
135
|
-
# end
|
136
|
-
# => ["<li class="choice">
|
137
|
-
# <label for="task_status_completed">
|
138
|
-
# <input type="radio" value="completed" name="task[status]" /> Completed
|
139
|
-
# </label>
|
140
|
-
# </li>",
|
141
|
-
# "<li class="choice">
|
142
|
-
# ...
|
143
|
-
# ]
|
144
|
-
#
|
145
|
-
# This method relies on ActiveAdmin
|
146
|
-
#
|
147
|
-
def to_html
|
148
|
-
choices = collection_with_unset #=> [["Completed", "completed"], ["In progress", "in_progress"], ["Unknown", "unset"]]
|
149
|
-
|
150
|
-
input_wrapping do
|
151
|
-
choices_wrapping do
|
152
|
-
legend_html << choices_group_wrapping do
|
153
|
-
choices.map { |choice|
|
154
|
-
choice_wrapping(choice_wrapping_html_options(choice)) do
|
155
|
-
choice_html(choice)
|
156
|
-
end
|
157
|
-
}.join("\n").html_safe
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
|
164
|
-
# @return [String] Label of the radio that stands for the unknown choice
|
165
|
-
#
|
166
|
-
def unset_label_translation
|
167
|
-
Formtastic::I18n.t(UNSET_KEY).presence or fail StandardError.new(MISSING_TRANSLATION_ERROR_MSG)
|
107
|
+
def selected?(choice)
|
108
|
+
ActiveModel::Type::Boolean.new.cast(choice_value(choice)) == object.public_send(method)
|
168
109
|
end
|
169
110
|
|
170
111
|
end
|
@@ -2,7 +2,11 @@
|
|
2
2
|
|
3
3
|
class ActiveRecord::Base
|
4
4
|
|
5
|
-
# @return [Array]
|
5
|
+
# @return [Array<Symbol>] names of Boolean columns which can store `NULL` values
|
6
|
+
# @example
|
7
|
+
# Company.tristate_column_names
|
8
|
+
# #=> [:is_profitable, :is_run_by_psychopaths, :evades_taxation, ...]
|
9
|
+
#
|
6
10
|
def self.tristate_column_names
|
7
11
|
columns.select { |col| col.type == :boolean && col.null }.map(&:name)
|
8
12
|
end
|
@@ -4,7 +4,7 @@ module ActiveModel
|
|
4
4
|
module Type
|
5
5
|
class Boolean < Value
|
6
6
|
|
7
|
-
NULL_VALUES = [nil, "", "null", :
|
7
|
+
NULL_VALUES = [nil, "", :null, "null", :nil, "nil"].to_set.freeze
|
8
8
|
|
9
9
|
private def cast_value(value)
|
10
10
|
NULL_VALUES.include?(value) ? nil : !FALSE_VALUES.include?(value)
|
@@ -1,8 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
require_relative "formtastic_tristate_radio/version"
|
2
|
+
require_relative "formtastic_tristate_radio/engine"
|
4
3
|
require_relative "../app/models/active_record/base"
|
5
|
-
# require_relative "../app/inputs/tristate_radio_input"
|
6
4
|
|
7
5
|
module FormtasticTristateRadio
|
6
|
+
|
7
|
+
class MissingTranslationError < StandardError; end
|
8
|
+
|
8
9
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: formtastic_tristate_radio
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sergey Pedan
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-11-
|
11
|
+
date: 2021-11-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: formtastic
|
@@ -115,7 +115,9 @@ executables: []
|
|
115
115
|
extensions: []
|
116
116
|
extra_rdoc_files:
|
117
117
|
- README.md
|
118
|
+
- CHANGELOG.md
|
118
119
|
files:
|
120
|
+
- CHANGELOG.md
|
119
121
|
- README.md
|
120
122
|
- Rakefile
|
121
123
|
- app/inputs/tristate_radio_input.rb
|
@@ -135,7 +137,7 @@ licenses:
|
|
135
137
|
- MIT
|
136
138
|
metadata:
|
137
139
|
changelog_uri: https://github.com/sergeypedan/formtastic-tristate-radio/blob/master/Changelog.md
|
138
|
-
documentation_uri: https://
|
140
|
+
documentation_uri: https://www.rubydoc.info/gems/
|
139
141
|
homepage_uri: https://github.com/sergeypedan/formtastic-tristate-radio
|
140
142
|
source_code_uri: https://github.com/sergeypedan/formtastic-tristate-radio
|
141
143
|
post_install_message:
|