client_side_validations 3.2.5 → 4.2.12
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/README.md +558 -0
- data/lib/client_side_validations/action_view/form_builder.rb +102 -84
- data/lib/client_side_validations/action_view/form_helper.rb +106 -111
- data/lib/client_side_validations/action_view/form_tag_helper.rb +13 -9
- data/lib/client_side_validations/action_view.rb +4 -3
- data/lib/client_side_validations/active_model/absence.rb +11 -0
- data/lib/client_side_validations/active_model/acceptance.rb +7 -6
- data/lib/client_side_validations/active_model/conditionals.rb +41 -0
- data/lib/client_side_validations/active_model/exclusion.rb +4 -24
- data/lib/client_side_validations/active_model/format.rb +14 -19
- data/lib/client_side_validations/active_model/inclusion.rb +4 -23
- data/lib/client_side_validations/active_model/length.rb +15 -15
- data/lib/client_side_validations/active_model/numericality.rb +25 -27
- data/lib/client_side_validations/active_model/presence.rb +7 -6
- data/lib/client_side_validations/active_model.rb +90 -82
- data/lib/client_side_validations/active_record/middleware.rb +48 -42
- data/lib/client_side_validations/active_record/uniqueness.rb +25 -21
- data/lib/client_side_validations/active_record.rb +5 -6
- data/lib/client_side_validations/config.rb +1 -1
- data/lib/client_side_validations/core_ext/range.rb +1 -2
- data/lib/client_side_validations/core_ext/regexp.rb +6 -4
- data/lib/client_side_validations/engine.rb +0 -1
- data/lib/client_side_validations/generators/rails_validations.rb +2 -3
- data/lib/client_side_validations/generators.rb +6 -3
- data/lib/client_side_validations/middleware.rb +37 -28
- data/lib/client_side_validations/version.rb +2 -1
- data/lib/client_side_validations.rb +0 -1
- data/lib/generators/client_side_validations/copy_assets_generator.rb +21 -25
- data/lib/generators/client_side_validations/install_generator.rb +0 -4
- data/lib/generators/templates/client_side_validations/initializer.rb +5 -2
- data/vendor/assets/javascripts/rails.validations.js +120 -100
- metadata +175 -62
- data/client_side_validations.gemspec +0 -32
|
@@ -1,31 +1,26 @@
|
|
|
1
|
-
module ClientSideValidations
|
|
2
|
-
module
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
if
|
|
1
|
+
module ClientSideValidations
|
|
2
|
+
module ActiveModel
|
|
3
|
+
module Format
|
|
4
|
+
def client_side_hash(model, attribute, force = nil)
|
|
5
|
+
options = self.options.dup
|
|
6
|
+
if options[:with].respond_to?(:call)
|
|
7
|
+
return unless force
|
|
7
8
|
options[:with] = options[:with].call(model)
|
|
8
9
|
build_client_side_hash(model, attribute, options)
|
|
9
|
-
|
|
10
|
-
return
|
|
11
|
-
end
|
|
12
|
-
elsif options[:without].respond_to?(:call)
|
|
13
|
-
if force
|
|
10
|
+
elsif options[:without].respond_to?(:call)
|
|
11
|
+
return unless force
|
|
14
12
|
options[:without] = options[:without].call(model)
|
|
15
13
|
build_client_side_hash(model, attribute, options)
|
|
16
14
|
else
|
|
17
|
-
|
|
15
|
+
super
|
|
18
16
|
end
|
|
19
|
-
else
|
|
20
|
-
super
|
|
21
17
|
end
|
|
22
|
-
end
|
|
23
18
|
|
|
24
|
-
|
|
19
|
+
private
|
|
25
20
|
|
|
26
|
-
|
|
27
|
-
|
|
21
|
+
def message_type
|
|
22
|
+
:invalid
|
|
23
|
+
end
|
|
28
24
|
end
|
|
29
25
|
end
|
|
30
26
|
end
|
|
31
|
-
|
|
@@ -1,26 +1,7 @@
|
|
|
1
|
-
module ClientSideValidations
|
|
2
|
-
module
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
if options[:in].respond_to?(:call)
|
|
6
|
-
if force
|
|
7
|
-
options = self.options.dup
|
|
8
|
-
options[:in] = options[:in].call(model)
|
|
9
|
-
hash = build_client_side_hash(model, attribute, options)
|
|
10
|
-
else
|
|
11
|
-
return
|
|
12
|
-
end
|
|
13
|
-
else
|
|
14
|
-
hash = build_client_side_hash(model, attribute, self.options.dup)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
if hash[:in].is_a?(Range)
|
|
18
|
-
hash[:range] = hash[:in]
|
|
19
|
-
hash.delete(:in)
|
|
20
|
-
end
|
|
21
|
-
hash
|
|
1
|
+
module ClientSideValidations
|
|
2
|
+
module ActiveModel
|
|
3
|
+
module Inclusion
|
|
4
|
+
include EnumerableValidator
|
|
22
5
|
end
|
|
23
|
-
|
|
24
6
|
end
|
|
25
7
|
end
|
|
26
|
-
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
module ClientSideValidations
|
|
2
|
-
module
|
|
1
|
+
module ClientSideValidations
|
|
2
|
+
module ActiveModel
|
|
3
|
+
module Length
|
|
4
|
+
def client_side_hash(model, attribute, _force = nil)
|
|
5
|
+
options = self.options.dup
|
|
6
|
+
hash = { messages: {} }
|
|
7
|
+
hash[:js_tokenizer] = options[:js_tokenizer] if options[:js_tokenizer]
|
|
8
|
+
hash[:allow_blank] = true if options[:allow_blank]
|
|
3
9
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
hash[:js_tokenizer] = options[:js_tokenizer] if options[:js_tokenizer]
|
|
8
|
-
hash[:allow_blank] = true if options[:allow_blank]
|
|
10
|
+
self.class::MESSAGES.each do |option, message_type|
|
|
11
|
+
count = options[option]
|
|
12
|
+
next unless count
|
|
9
13
|
|
|
10
|
-
self.class::MESSAGES.each do |option, message_type|
|
|
11
|
-
if count = options[option]
|
|
12
14
|
options[:message] = options[message_type] if options[message_type].present?
|
|
13
15
|
options.delete(:message) if options[:message].nil?
|
|
14
|
-
hash[:messages][option] = model.errors.generate_message(attribute, message_type, options.merge(:
|
|
16
|
+
hash[:messages][option] = model.errors.generate_message(attribute, message_type, options.merge(count: count))
|
|
15
17
|
hash[option] = count
|
|
16
18
|
end
|
|
17
|
-
end
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
copy_conditional_attributes(hash, options)
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
hash
|
|
23
|
+
end
|
|
22
24
|
end
|
|
23
|
-
|
|
24
25
|
end
|
|
25
26
|
end
|
|
26
|
-
|
|
@@ -1,42 +1,40 @@
|
|
|
1
|
-
module ClientSideValidations
|
|
2
|
-
module
|
|
1
|
+
module ClientSideValidations
|
|
2
|
+
module ActiveModel
|
|
3
|
+
module Numericality
|
|
4
|
+
@@option_map = {}
|
|
3
5
|
|
|
4
|
-
|
|
6
|
+
def self.included(base)
|
|
7
|
+
@@option_map.merge!(base::CHECKS.keys.inject({}) { |acc, elem| acc.merge!(elem => elem) })
|
|
8
|
+
end
|
|
5
9
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+
def client_side_hash(model, attribute, force = nil)
|
|
11
|
+
options = self.options.dup
|
|
12
|
+
hash = { messages: { numericality: model.errors.generate_message(attribute, :not_a_number, options) } }
|
|
9
13
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
if options[:only_integer]
|
|
15
|
+
hash[:messages][:only_integer] = model.errors.generate_message(attribute, :not_an_integer, options)
|
|
16
|
+
hash[:only_integer] = true
|
|
17
|
+
end
|
|
13
18
|
|
|
14
|
-
|
|
15
|
-
hash[:messages][:only_integer] = model.errors.generate_message(attribute, :not_an_integer, options)
|
|
16
|
-
hash[:only_integer] = true
|
|
17
|
-
end
|
|
19
|
+
hash[:allow_blank] = true if options[:allow_nil] || options[:allow_blank]
|
|
18
20
|
|
|
19
|
-
|
|
21
|
+
@@option_map.each do |option, message_type|
|
|
22
|
+
count = options[option]
|
|
23
|
+
next unless count
|
|
20
24
|
|
|
21
|
-
OPTION_MAP.each do |option, message_type|
|
|
22
|
-
if count = options[option]
|
|
23
25
|
if count.respond_to?(:call)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
else
|
|
27
|
-
next
|
|
28
|
-
end
|
|
26
|
+
next unless force
|
|
27
|
+
count = count.call(model)
|
|
29
28
|
end
|
|
30
|
-
|
|
29
|
+
|
|
30
|
+
hash[:messages][option] = model.errors.generate_message(attribute, message_type, options.merge(count: count))
|
|
31
31
|
hash[option] = count
|
|
32
32
|
end
|
|
33
|
-
end
|
|
34
33
|
|
|
35
|
-
|
|
34
|
+
copy_conditional_attributes(hash, options)
|
|
36
35
|
|
|
37
|
-
|
|
36
|
+
hash
|
|
37
|
+
end
|
|
38
38
|
end
|
|
39
|
-
|
|
40
39
|
end
|
|
41
40
|
end
|
|
42
|
-
|
|
@@ -1,40 +1,42 @@
|
|
|
1
1
|
require 'client_side_validations/core_ext'
|
|
2
|
+
require 'client_side_validations/active_model/conditionals'
|
|
2
3
|
|
|
3
|
-
module ClientSideValidations
|
|
4
|
-
module
|
|
4
|
+
module ClientSideValidations
|
|
5
|
+
module ActiveModel
|
|
6
|
+
module Validator
|
|
7
|
+
def client_side_hash(model, attribute, _force = nil)
|
|
8
|
+
build_client_side_hash(model, attribute, options.dup)
|
|
9
|
+
end
|
|
5
10
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
11
|
+
def copy_conditional_attributes(to, from)
|
|
12
|
+
[:if, :unless].each { |key| to[key] = from[key] if from[key].present? }
|
|
13
|
+
end
|
|
9
14
|
|
|
10
|
-
|
|
11
|
-
[:if, :unless].each { |key| to[key] = from[key] if from[key].present? }
|
|
12
|
-
end
|
|
15
|
+
private
|
|
13
16
|
|
|
14
|
-
|
|
17
|
+
def build_client_side_hash(model, attribute, options)
|
|
18
|
+
{ message: model.errors.generate_message(attribute, message_type, options) }.merge(options.except(*::ActiveModel::Errors::CALLBACKS_OPTIONS - [:allow_blank, :if, :unless]))
|
|
19
|
+
end
|
|
15
20
|
|
|
16
|
-
|
|
17
|
-
|
|
21
|
+
def message_type
|
|
22
|
+
kind
|
|
23
|
+
end
|
|
18
24
|
end
|
|
19
25
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
end
|
|
23
|
-
end
|
|
26
|
+
module Validations
|
|
27
|
+
include ClientSideValidations::ActiveModel::Conditionals
|
|
24
28
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
unless [nil, :block].include?(attr[0])
|
|
29
|
+
def client_side_validation_hash(force = nil)
|
|
30
|
+
_validators.inject({}) do |attr_hash, attr|
|
|
31
|
+
return attr_hash if [nil, :block].include?(attr[0])
|
|
29
32
|
|
|
30
|
-
validator_hash = attr[1].
|
|
31
|
-
|
|
32
|
-
if client_side_hash = validator.client_side_hash(self, attr[0], extract_force_option(attr[0], force))
|
|
33
|
-
kind_hash[validator.kind] << client_side_hash.except(:on, :if, :unless)
|
|
34
|
-
end
|
|
35
|
-
end
|
|
33
|
+
validator_hash = attr[1].each_with_object(Hash.new { |h, k| h[k] = [] }) do |validator, kind_hash|
|
|
34
|
+
next unless can_use_for_client_side_validation?(attr[0], validator, force)
|
|
36
35
|
|
|
37
|
-
|
|
36
|
+
client_side_hash = validator.client_side_hash(self, attr[0], extract_force_option(attr[0], force))
|
|
37
|
+
if client_side_hash
|
|
38
|
+
kind_hash[validator.kind] << client_side_hash.except(:on, :if, :unless)
|
|
39
|
+
end
|
|
38
40
|
end
|
|
39
41
|
|
|
40
42
|
if validator_hash.present?
|
|
@@ -42,91 +44,99 @@ module ClientSideValidations::ActiveModel
|
|
|
42
44
|
else
|
|
43
45
|
attr_hash
|
|
44
46
|
end
|
|
45
|
-
else
|
|
46
|
-
attr_hash
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
|
-
end
|
|
50
49
|
|
|
51
|
-
|
|
50
|
+
private
|
|
52
51
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
nil
|
|
52
|
+
def extract_force_option(attr, force)
|
|
53
|
+
case force
|
|
54
|
+
when FalseClass, TrueClass, NilClass
|
|
55
|
+
force
|
|
56
|
+
when Hash
|
|
57
|
+
extract_force_option(nil, force[attr])
|
|
58
|
+
end
|
|
61
59
|
end
|
|
62
|
-
end
|
|
63
60
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
else
|
|
61
|
+
def can_use_for_client_side_validation?(attr, validator, force)
|
|
62
|
+
return false if validator_turned_off?(attr, validator, force)
|
|
63
|
+
|
|
68
64
|
# Yeah yeah, #new_record? is not part of ActiveModel :p
|
|
69
|
-
result = ((
|
|
70
|
-
result
|
|
65
|
+
result = ((respond_to?(:new_record?) && validator.options[:on] == (new_record? ? :create : :update)) || validator.options[:on].nil?)
|
|
66
|
+
result &&= validator.kind != :block
|
|
71
67
|
|
|
72
68
|
if validator.options[:if] || validator.options[:unless]
|
|
73
69
|
if validator.options[:if] && validator.options[:if] =~ /changed\?/
|
|
74
70
|
result = true
|
|
75
|
-
else
|
|
71
|
+
else
|
|
72
|
+
result = can_force_validator?(attr, validator, force)
|
|
76
73
|
if validator.options[:if]
|
|
77
|
-
result
|
|
74
|
+
result &&= run_conditionals(validator.options[:if], :if)
|
|
78
75
|
end
|
|
79
76
|
if validator.options[:unless]
|
|
80
|
-
result
|
|
77
|
+
result &&= run_conditionals(validator.options[:unless], :unless)
|
|
81
78
|
end
|
|
82
79
|
end
|
|
83
80
|
end
|
|
84
|
-
end
|
|
85
81
|
|
|
86
|
-
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def run_conditional(method_name_value_or_proc)
|
|
90
|
-
if method_name_value_or_proc.respond_to?(:call)
|
|
91
|
-
method_name_value_or_proc.call(self)
|
|
92
|
-
else
|
|
93
|
-
self.send(method_name_value_or_proc)
|
|
82
|
+
result
|
|
94
83
|
end
|
|
95
|
-
end
|
|
96
84
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
true
|
|
101
|
-
when Hash
|
|
102
|
-
case force[attr]
|
|
85
|
+
def validator_turned_off?(attr, validator, force)
|
|
86
|
+
return true if ::ClientSideValidations::Config.disabled_validators.include?(validator.kind)
|
|
87
|
+
case force
|
|
103
88
|
when FalseClass
|
|
104
89
|
true
|
|
105
90
|
when Hash
|
|
106
|
-
force[attr]
|
|
91
|
+
case force[attr]
|
|
92
|
+
when FalseClass
|
|
93
|
+
true
|
|
94
|
+
when Hash
|
|
95
|
+
force[attr][validator.kind] == false
|
|
96
|
+
else
|
|
97
|
+
false
|
|
98
|
+
end
|
|
107
99
|
else
|
|
108
100
|
false
|
|
109
101
|
end
|
|
110
|
-
else
|
|
111
|
-
::ClientSideValidations::Config.disabled_validators.include?(validator.kind)
|
|
112
102
|
end
|
|
113
|
-
end
|
|
114
103
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
when TrueClass
|
|
118
|
-
true
|
|
119
|
-
when Hash
|
|
120
|
-
case force[attr]
|
|
104
|
+
def can_force_validator?(attr, validator, force)
|
|
105
|
+
case force
|
|
121
106
|
when TrueClass
|
|
122
107
|
true
|
|
123
108
|
when Hash
|
|
124
|
-
force[attr]
|
|
109
|
+
case force[attr]
|
|
110
|
+
when TrueClass
|
|
111
|
+
true
|
|
112
|
+
when Hash
|
|
113
|
+
force[attr][validator.kind]
|
|
114
|
+
else
|
|
115
|
+
false
|
|
116
|
+
end
|
|
125
117
|
else
|
|
126
118
|
false
|
|
127
119
|
end
|
|
128
|
-
|
|
129
|
-
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
module EnumerableValidator
|
|
124
|
+
def client_side_hash(model, attribute, force = nil)
|
|
125
|
+
options = self.options.dup
|
|
126
|
+
|
|
127
|
+
if options[:in].respond_to?(:call)
|
|
128
|
+
return unless force
|
|
129
|
+
options[:in] = options[:in].call(model)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
hash = build_client_side_hash(model, attribute, options)
|
|
133
|
+
|
|
134
|
+
if hash[:in].is_a?(Range)
|
|
135
|
+
hash[:range] = hash[:in]
|
|
136
|
+
hash.delete(:in)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
hash
|
|
130
140
|
end
|
|
131
141
|
end
|
|
132
142
|
end
|
|
@@ -135,9 +145,7 @@ end
|
|
|
135
145
|
ActiveModel::Validator.send(:include, ClientSideValidations::ActiveModel::Validator)
|
|
136
146
|
ActiveModel::Validations.send(:include, ClientSideValidations::ActiveModel::Validations)
|
|
137
147
|
|
|
138
|
-
%w
|
|
139
|
-
require "client_side_validations/active_model/#{validator}"
|
|
140
|
-
validator.
|
|
141
|
-
eval "ActiveModel::Validations::#{validator}Validator.send(:include, ClientSideValidations::ActiveModel::#{validator})"
|
|
148
|
+
%w(Absence Acceptance Exclusion Format Inclusion Length Numericality Presence).each do |validator|
|
|
149
|
+
require "client_side_validations/active_model/#{validator.downcase}"
|
|
150
|
+
ActiveModel::Validations.const_get("#{validator}Validator").send :include, ClientSideValidations::ActiveModel.const_get(validator)
|
|
142
151
|
end
|
|
143
|
-
|
|
@@ -1,59 +1,65 @@
|
|
|
1
|
-
module ClientSideValidations
|
|
2
|
-
|
|
1
|
+
module ClientSideValidations
|
|
2
|
+
module ActiveRecord
|
|
3
|
+
class Middleware
|
|
4
|
+
def self.class?(klass)
|
|
5
|
+
klass.abstract_class.blank? && klass < ::ActiveRecord::Base
|
|
6
|
+
end
|
|
3
7
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
8
|
+
def self.unique?(klass, attribute, value, params)
|
|
9
|
+
klass = find_topmost_superclass(klass)
|
|
10
|
+
column = klass.columns_hash[attribute.to_s]
|
|
11
|
+
value = type_cast_value(column, value)
|
|
7
12
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
value = type_cast_value(klass, attribute, value)
|
|
11
|
-
column = klass.columns_hash[attribute.to_s]
|
|
12
|
-
value = column.limit ? value.to_s.mb_chars[0, column.limit] : value.to_s if column.text?
|
|
13
|
+
sql = sql_statement(klass, attribute, value, params)
|
|
14
|
+
relation = Arel::Nodes::SqlLiteral.new(sql)
|
|
13
15
|
|
|
14
|
-
|
|
16
|
+
klass.where(relation).empty?
|
|
17
|
+
end
|
|
15
18
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
def self.sql_statement(klass, attribute, value, params)
|
|
20
|
+
sql = []
|
|
21
|
+
t = klass.arel_table
|
|
22
|
+
|
|
23
|
+
if params[:case_sensitive] == 'true'
|
|
24
|
+
sql << 'BINARY' if t.engine.connection.adapter_name =~ /^mysql/i
|
|
25
|
+
sql << t[attribute].eq(value).to_sql
|
|
19
26
|
else
|
|
20
|
-
|
|
27
|
+
escaped_value = value.gsub(/[%_]/, '\\\\\0')
|
|
28
|
+
sql << "#{t[attribute].matches(escaped_value).to_sql} ESCAPE '\\'"
|
|
21
29
|
end
|
|
22
|
-
else
|
|
23
|
-
relation = t[attribute].matches(value)
|
|
24
|
-
end
|
|
25
30
|
|
|
26
|
-
|
|
27
|
-
relation = Arel::Nodes::SqlLiteral.new("BINARY #{t[attribute].eq(value).to_sql} AND #{t[klass.primary_key].not_eq(params[:id]).to_sql}")
|
|
28
|
-
else
|
|
29
|
-
relation = relation.and(t[klass.primary_key].not_eq(params[:id])) if params[:id]
|
|
30
|
-
end
|
|
31
|
+
sql << "AND #{t[klass.primary_key].not_eq(params[:id]).to_sql}" if params[:id]
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
relation = Arel::Nodes::SqlLiteral.new("#{relation} AND #{t[attribute].eq(value).to_sql}")
|
|
36
|
-
else
|
|
37
|
-
relation = relation.and(t[attribute].eq(value))
|
|
33
|
+
(params[:scope] || {}).each do |scope_attribute, scope_value|
|
|
34
|
+
scope_value = type_cast_value(klass.columns_hash[scope_attribute], scope_value)
|
|
35
|
+
sql << "AND #{t[scope_attribute].eq(scope_value).to_sql}"
|
|
38
36
|
end
|
|
39
|
-
end
|
|
40
37
|
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
sql.join ' '
|
|
39
|
+
end
|
|
43
40
|
|
|
44
|
-
|
|
41
|
+
def self.type_cast_value(column, value)
|
|
42
|
+
value =
|
|
43
|
+
if column.respond_to?(:type_cast)
|
|
44
|
+
column.type_cast(value)
|
|
45
|
+
else
|
|
46
|
+
column.type_cast_from_database(value)
|
|
47
|
+
end
|
|
45
48
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
if column.limit && value.is_a?(String)
|
|
50
|
+
value.mb_chars[0, column.limit]
|
|
51
|
+
else
|
|
52
|
+
value
|
|
53
|
+
end
|
|
54
|
+
end
|
|
49
55
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
56
|
+
def self.find_topmost_superclass(klass)
|
|
57
|
+
if class?(klass.superclass)
|
|
58
|
+
find_topmost_superclass(klass.superclass)
|
|
59
|
+
else
|
|
60
|
+
klass
|
|
61
|
+
end
|
|
55
62
|
end
|
|
56
63
|
end
|
|
57
|
-
|
|
58
64
|
end
|
|
59
65
|
end
|
|
@@ -1,29 +1,33 @@
|
|
|
1
|
-
module ClientSideValidations
|
|
2
|
-
module
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
module ClientSideValidations
|
|
2
|
+
module ActiveRecord
|
|
3
|
+
module Uniqueness
|
|
4
|
+
def client_side_hash(model, attribute, _force = nil)
|
|
5
|
+
hash = {}
|
|
6
|
+
hash[:message] = model.errors.generate_message(attribute, message_type, options.except(:scope))
|
|
7
|
+
hash[:case_sensitive] = options[:case_sensitive]
|
|
8
|
+
hash[:id] = model.id unless model.new_record?
|
|
9
|
+
hash[:allow_blank] = true if options[:allow_blank]
|
|
10
|
+
|
|
11
|
+
if options.key?(:client_validations) && options[:client_validations].key?(:class)
|
|
12
|
+
hash[:class] = options[:client_validations][:class].underscore
|
|
13
|
+
elsif model.class.name.demodulize != model.class.name
|
|
14
|
+
hash[:class] = model.class.name.underscore
|
|
12
15
|
end
|
|
13
|
-
end
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
if options.key?(:scope) && options[:scope].present?
|
|
18
|
+
hash[:scope] = Array.wrap(options[:scope]).inject({}) do |scope_hash, scope_item|
|
|
19
|
+
scope_hash.merge!(scope_item => model.send(scope_item))
|
|
20
|
+
end
|
|
21
|
+
end
|
|
18
22
|
|
|
19
|
-
|
|
20
|
-
|
|
23
|
+
hash
|
|
24
|
+
end
|
|
21
25
|
|
|
22
|
-
|
|
26
|
+
private
|
|
23
27
|
|
|
24
|
-
|
|
25
|
-
|
|
28
|
+
def message_type
|
|
29
|
+
:taken
|
|
30
|
+
end
|
|
26
31
|
end
|
|
27
32
|
end
|
|
28
33
|
end
|
|
29
|
-
|
|
@@ -2,11 +2,10 @@ require 'client_side_validations/active_model'
|
|
|
2
2
|
require 'client_side_validations/middleware'
|
|
3
3
|
require 'client_side_validations/active_record/middleware'
|
|
4
4
|
|
|
5
|
-
%w{uniqueness}.each do |validator|
|
|
6
|
-
require "client_side_validations/active_record/#{validator}"
|
|
7
|
-
validator.capitalize!
|
|
8
|
-
eval "ActiveRecord::Validations::#{validator}Validator.send(:include, ClientSideValidations::ActiveRecord::#{validator})"
|
|
9
|
-
end
|
|
10
|
-
|
|
11
5
|
ActiveRecord::Base.send(:include, ClientSideValidations::ActiveModel::Validations)
|
|
12
6
|
ClientSideValidations::Middleware::Uniqueness.register_orm(ClientSideValidations::ActiveRecord::Middleware)
|
|
7
|
+
|
|
8
|
+
%w(Uniqueness).each do |validator|
|
|
9
|
+
require "client_side_validations/active_record/#{validator.downcase}"
|
|
10
|
+
ActiveRecord::Validations.const_get("#{validator}Validator").send :include, ClientSideValidations::ActiveRecord.const_get(validator)
|
|
11
|
+
end
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
+
require 'js_regex'
|
|
2
|
+
|
|
1
3
|
class Regexp
|
|
2
|
-
def as_json(
|
|
3
|
-
|
|
4
|
+
def as_json(*)
|
|
5
|
+
JsRegex.new(self).to_h
|
|
4
6
|
end
|
|
5
7
|
|
|
6
8
|
def to_json(options = nil)
|
|
7
|
-
as_json(options)
|
|
9
|
+
as_json(options)
|
|
8
10
|
end
|
|
9
11
|
|
|
10
|
-
def encode_json(
|
|
12
|
+
def encode_json(_encoder)
|
|
11
13
|
inspect
|
|
12
14
|
end
|
|
13
15
|
end
|