formtastic_tristate_radio 0.1.0 → 0.2.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.
- 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
|
+
[](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:
|