validation_sync 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/generate_validations.js.erb +138 -0
- data/app/assets/javascripts/validation_sync.js +2 -1
- data/app/helpers/validation_sync_form_helper.rb +12 -71
- data/lib/validation_sync/engine.rb +2 -0
- data/lib/validation_sync/validation_builder.rb +139 -0
- data/lib/validation_sync/version.rb +1 -1
- data/lib/validation_sync.rb +1 -0
- data/spec/dummy/app/controllers/posts_controller.rb +1 -1
- data/spec/dummy/app/controllers/users_controller.rb +58 -0
- data/spec/dummy/app/models/post.rb +15 -4
- data/spec/dummy/app/models/user.rb +11 -0
- data/spec/dummy/app/views/posts/_form.html.erb +8 -0
- data/spec/dummy/app/views/posts/show.html.erb +5 -0
- data/spec/dummy/app/views/users/_form.html.erb +33 -0
- data/spec/dummy/app/views/users/edit.html.erb +6 -0
- data/spec/dummy/app/views/users/index.html.erb +29 -0
- data/spec/dummy/app/views/users/new.html.erb +5 -0
- data/spec/dummy/app/views/users/show.html.erb +14 -0
- data/spec/dummy/config/application.rb +1 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20140211200846_create_users.rb +10 -0
- data/spec/dummy/db/migrate/20140212170448_add_order_to_posts.rb +5 -0
- data/spec/dummy/db/migrate/20140212173012_add_user_id_to_posts.rb +5 -0
- data/spec/dummy/db/schema.rb +10 -1
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +7256 -0
- data/spec/dummy/log/test.log +6037 -0
- data/spec/dummy/spec/factories/posts.rb +26 -0
- data/spec/dummy/spec/factories/users.rb +14 -0
- data/spec/dummy/spec/models/post_spec.rb +98 -0
- data/spec/dummy/spec/models/user_spec.rb +27 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/10c6f05e183df4466be1e0171868fbd3 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/254f7fcb30f60607963da8bbb320eb25 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/256916ba749d0c14e36b55d4b382e9f5 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/38ec44893aed52b20a20a929a47e0ad9 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/4a4d6fda449d6b443e5b29ccb755c732 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/513dd40b9b52367f54d64438a9d802b9 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/56146675dbad13c72d3eb9ebd823dc11 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/7aaf7da4e6ec4c84cc7948fb20c35064 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/ba165ee56ce37f61865fe03d6503539b +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/bfaeb96080cc4d8ba400fbdcd1d4aab2 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/c4f1b332263aa5004a8ac54ca9530510 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/c63406c52c03bbb24922ded6ebb0e0a2 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/cbc66bd36b3aa4411f9ce20da0fd37a0 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/d7874cf8a5946ec3899e5bb627905ca5 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/e1d4998592ddfea795aca82d742d9478 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/0f11e0b3e0ece93d6c047318f2e5497d +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/10c6f05e183df4466be1e0171868fbd3 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/122e92d06837af295d6c941999a8d48f +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/254f7fcb30f60607963da8bbb320eb25 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/256916ba749d0c14e36b55d4b382e9f5 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/4a4d6fda449d6b443e5b29ccb755c732 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/56146675dbad13c72d3eb9ebd823dc11 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/bfaeb96080cc4d8ba400fbdcd1d4aab2 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/c4f1b332263aa5004a8ac54ca9530510 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/d7874cf8a5946ec3899e5bb627905ca5 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/e1d4998592ddfea795aca82d742d9478 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/spec/dummy/tmp/capybara/capybara-201402111733312899331645.html +39 -0
- data/spec/dummy/tmp/capybara/capybara-201402111742049902988712.html +39 -0
- data/spec/dummy/tmp/capybara/capybara-201402111743461497527818.html +39 -0
- data/spec/dummy/tmp/capybara/capybara-201402121034216891460553.html +39 -0
- data/spec/dummy/tmp/capybara/capybara-201402121100145511229652.html +39 -0
- data/spec/dummy/tmp/capybara/capybara-20140212110749239625833.html +39 -0
- data/spec/dummy/tmp/capybara/capybara-201402121110009350488348.html +39 -0
- data/spec/dummy/tmp/capybara/capybara-201402121242315707153414.html +54 -0
- data/spec/dummy/tmp/capybara/capybara-2014021212463939561980.html +47 -0
- data/spec/dummy/tmp/capybara/capybara-201402121308362867044001.html +47 -0
- data/spec/dummy/tmp/capybara/capybara-201402121309286432044699.html +47 -0
- data/spec/dummy/tmp/capybara/capybara-201402121506235794052148.html +39 -0
- data/spec/dummy/tmp/capybara/capybara-201402121507316558835315.html +27 -0
- data/spec/dummy/tmp/capybara/capybara-201402121512202956445364.html +39 -0
- data/spec/dummy/tmp/capybara/capybara-201402121517176338336364.html +39 -0
- data/spec/dummy/tmp/capybara/capybara-201402121518121290133083.html +39 -0
- data/spec/dummy/tmp/pids/server.pid +1 -0
- data/spec/features/form_interactions_spec.rb +153 -0
- data/spec/features/generate_validations_spec.rb +26 -0
- data/spec/helpers/validation_sync_form_helper_spec.rb +24 -0
- data/spec/lib/validation_builder_spec.rb +173 -0
- data/spec/spec_helper.rb +7 -1
- metadata +120 -11
- data/app/assets/javascripts/validations.js.coffee.erb +0 -51
- data/spec/dummy/app/assets/javascripts/posts.js +0 -2
- data/spec/dummy/app/assets/stylesheets/posts.css +0 -4
- data/spec/features/form_validation_spec.rb +0 -53
- data/spec/helpers/form_helper_spec.rb +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 74fc180dc9264157b728b7fa8d5047a814a6ffb7
|
4
|
+
data.tar.gz: ebd5d1cacf26e5a52a775d17a05b240773aab194
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 00818ccdfc64c8e780001edbdefc9026c84c0ac3a13ae90346d87ff15eac26b8b61cbb5206a4d2b4070c006233d0e85040152025f99d7ec7d346aafd0565f601
|
7
|
+
data.tar.gz: 77f71cbf6d4710739b8d9a8f615437dc6e40edfa3782dd15d4c57cfd1d29588d436a78d5bc2906a954c50fb868bbe9acd916d68cbe9a10ed1ca811d793a77634
|
@@ -0,0 +1,138 @@
|
|
1
|
+
<%
|
2
|
+
# Our Builder object
|
3
|
+
@builder = ValidationBuilder.new
|
4
|
+
|
5
|
+
# Helpers for ActiveRecord/Model Validators
|
6
|
+
presence_validator = ActiveRecord::Validations::PresenceValidator
|
7
|
+
number_validator = ActiveModel::Validations::NumericalityValidator
|
8
|
+
confirmation_validator = ActiveModel::Validations::ConfirmationValidator
|
9
|
+
%>
|
10
|
+
|
11
|
+
|
12
|
+
var ValidationSync;
|
13
|
+
|
14
|
+
ValidationSync = {
|
15
|
+
|
16
|
+
init: function() {
|
17
|
+
<% @builder.find_all_models.each do |model| %>
|
18
|
+
|
19
|
+
// validate only if a relevant form is present
|
20
|
+
if ( $(".new_<%= model[:name] %>[data-sync-validations='true'], .edit_<%= model[:name] %>[data-sync-validations='true']").length ){
|
21
|
+
ValidationSync.validate<%= model[:name].camelize %>();
|
22
|
+
}
|
23
|
+
|
24
|
+
<% end %>
|
25
|
+
},
|
26
|
+
|
27
|
+
|
28
|
+
// build a validateModel() method for each ActiveRecord model
|
29
|
+
<% @builder.find_all_models.each do |model| %>
|
30
|
+
|
31
|
+
validate<%= model[:name].camelize %>: function() {
|
32
|
+
$forms = $(".new_<%= model[:name] %>[data-sync-validations='true'], .edit_<%= model[:name] %>[data-sync-validations='true']");
|
33
|
+
$forms.validate({
|
34
|
+
|
35
|
+
|
36
|
+
rules: {
|
37
|
+
<% model[:attributes].each do |attr|
|
38
|
+
|
39
|
+
# Set default arguments
|
40
|
+
@builder.object_name = model[:name]
|
41
|
+
@builder.method = attr.to_sym
|
42
|
+
|
43
|
+
%>
|
44
|
+
|
45
|
+
"<%= model[:name] %>[<%= attr %>]": {
|
46
|
+
|
47
|
+
|
48
|
+
// REQUIRED: if we use the presence_validator
|
49
|
+
// ----------------------------------------------------------------
|
50
|
+
<% if @builder.check_model_validation(presence_validator) %>
|
51
|
+
required: true,
|
52
|
+
|
53
|
+
// REQUIRED: if we use the number_validator, :allow_nil => false
|
54
|
+
// ----------------------------------------------------------------
|
55
|
+
<% elsif @builder.check_model_validation(number_validator) %>
|
56
|
+
// with allow_nil = false
|
57
|
+
<% if @builder.get_validation_attr(number_validator, :allow_nil).nil? %>
|
58
|
+
required: true,
|
59
|
+
<% end %>
|
60
|
+
<% end # required %>
|
61
|
+
|
62
|
+
|
63
|
+
// NUMBER: if we use the number_validator
|
64
|
+
// ----------------------------------------------------------------
|
65
|
+
<% if @builder.check_model_validation(number_validator) %>
|
66
|
+
number: true,
|
67
|
+
<% end %>
|
68
|
+
|
69
|
+
|
70
|
+
// EQUALTO: if we use the confirmation_validator
|
71
|
+
// ----------------------------------------------------------------
|
72
|
+
<% if @builder.check_model_validation(confirmation_validator) %>
|
73
|
+
equalTo: "#<%= model[:name] %>_<%= attr %>_confirmation",
|
74
|
+
<% end %>
|
75
|
+
|
76
|
+
|
77
|
+
},
|
78
|
+
<% end # model[:attributes].each %>
|
79
|
+
},
|
80
|
+
|
81
|
+
|
82
|
+
messages: {
|
83
|
+
<% model[:attributes].each do |attr|
|
84
|
+
|
85
|
+
# Set default arguments
|
86
|
+
@builder.object_name = model[:name]
|
87
|
+
@builder.method = attr.to_sym
|
88
|
+
|
89
|
+
%>
|
90
|
+
|
91
|
+
"<%= model[:name] %>[<%= attr %>]": {
|
92
|
+
|
93
|
+
|
94
|
+
// REQUIRED: if we use the presence_validator
|
95
|
+
// ----------------------------------------------------------------
|
96
|
+
<% if @builder.check_model_validation(presence_validator) %>
|
97
|
+
required: "<%= @builder.get_validation_message(presence_validator) %>",
|
98
|
+
|
99
|
+
// REQUIRED: if we use the number_validator, :allow_nil => false
|
100
|
+
// ----------------------------------------------------------------
|
101
|
+
<% elsif @builder.check_model_validation(number_validator) %>
|
102
|
+
// with allow_nil = false
|
103
|
+
<% if @builder.get_validation_attr(number_validator, :allow_nil).nil? %>
|
104
|
+
required: "<%= @builder.get_validation_message(number_validator) %>",
|
105
|
+
<% end %>
|
106
|
+
<% end # required %>
|
107
|
+
|
108
|
+
|
109
|
+
// NUMBER: if we use the number_validator
|
110
|
+
// ----------------------------------------------------------------
|
111
|
+
<% if @builder.check_model_validation(number_validator) %>
|
112
|
+
number: "<%= @builder.get_validation_message(number_validator) %>",
|
113
|
+
<% end %>
|
114
|
+
|
115
|
+
|
116
|
+
// EQUALTO: if we use the confirmation_validator
|
117
|
+
// ----------------------------------------------------------------
|
118
|
+
<% if @builder.check_model_validation(confirmation_validator) %>
|
119
|
+
equalTo: "<%= @builder.get_validation_message(confirmation_validator) %>",
|
120
|
+
<% end %>
|
121
|
+
|
122
|
+
|
123
|
+
},
|
124
|
+
<% end # model[:attributes].each %>
|
125
|
+
},
|
126
|
+
|
127
|
+
|
128
|
+
}); // $forms.validate()
|
129
|
+
}, // validateModel
|
130
|
+
|
131
|
+
<% end # @builder.find_all_models.each %>
|
132
|
+
}
|
133
|
+
|
134
|
+
|
135
|
+
|
136
|
+
|
137
|
+
// Fire init() on ready (or page:load for turbolinks)
|
138
|
+
$(document).on('ready page:load', ValidationSync.init);
|
@@ -1,87 +1,28 @@
|
|
1
1
|
module ValidationSyncFormHelper
|
2
2
|
|
3
|
+
|
4
|
+
#
|
5
|
+
# Override the default form_for method to include a
|
6
|
+
# data-sync-validations attribute, set to true / false
|
7
|
+
# returns html
|
8
|
+
#
|
3
9
|
def form_for(record, options = {}, &block)
|
4
10
|
# If the html_options / data hashes are not
|
5
|
-
# set, then let's
|
11
|
+
# set, then let's add them as empty hashes
|
6
12
|
options[:html] ||= {}
|
7
13
|
options[:html][:data] ||= {}
|
8
14
|
|
15
|
+
# Default to validate = false
|
16
|
+
options[:validate] ||= false
|
17
|
+
|
9
18
|
# Add our data-sync-validations attribute
|
10
19
|
options[:html][:data][:sync_validations] = options[:validate].to_s
|
11
20
|
|
21
|
+
# Let the Rails defaults take it from here
|
12
22
|
super
|
13
23
|
end
|
14
24
|
|
15
25
|
|
16
|
-
def find_all_models
|
17
|
-
models = []
|
18
|
-
|
19
|
-
# iterate over all files in folder
|
20
|
-
folder = File.join(ValidationSync::Engine::APP_ROOT, "app", "models")
|
21
|
-
|
22
|
-
Dir[File.join(folder, "*")].each do |filename|
|
23
|
-
klass = File.basename(filename, '.rb').camelize.constantize
|
24
|
-
next unless klass.ancestors.include?(ActiveRecord::Base)
|
25
|
-
|
26
|
-
model = {
|
27
|
-
name: klass.name.downcase,
|
28
|
-
attributes: klass.new.attributes.keys
|
29
|
-
}
|
30
|
-
|
31
|
-
models << model
|
32
|
-
end
|
33
|
-
|
34
|
-
return models
|
35
|
-
end
|
36
|
-
|
37
|
-
|
38
|
-
#
|
39
|
-
# Check to see if a given model attribute uses a given validation
|
40
|
-
# returns true/false
|
41
|
-
#
|
42
|
-
def check_model_validation(object_name, method, validation)
|
43
|
-
object_class = object_name.camelize.constantize
|
44
|
-
if object_class.validators_on(method).map(&:class).include? validation
|
45
|
-
true
|
46
|
-
else
|
47
|
-
false
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
|
52
|
-
#
|
53
|
-
# Check to see if a given model attribute uses a given validation
|
54
|
-
# returns the specified validation option
|
55
|
-
#
|
56
|
-
def get_validation_attr(object_name, method, validation, option)
|
57
|
-
if check_model_validation(object_name, method, validation)
|
58
|
-
object_class = object_name.camelize.constantize
|
59
|
-
attr = object_class.validators_on(method).find { |v| v.class == validation }
|
60
|
-
return (attr.options[option]) ? attr.options[option] : nil
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
|
65
|
-
def get_validation_message(object_name, method, validation)
|
66
|
-
object_class = object_name.camelize.constantize
|
67
|
-
|
68
|
-
# we validate this attribute
|
69
|
-
if val = object_class.validators_on(method).find { |v| v.class == validation }
|
70
|
-
|
71
|
-
if val.options[:message]
|
72
|
-
# custom message is defined
|
73
|
-
return val.options[:message]
|
74
|
-
else
|
75
|
-
# fall back to the default message
|
76
|
-
return "TODO: add default error messages"
|
77
|
-
end
|
78
|
-
|
79
|
-
else
|
80
|
-
# we don't validate this attribute
|
81
|
-
nil
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
26
|
|
86
|
-
end
|
27
|
+
end # ValidationSyncFormHelper
|
87
28
|
|
@@ -0,0 +1,139 @@
|
|
1
|
+
class ValidationBuilder
|
2
|
+
|
3
|
+
# allows us to set default arguments for the builder
|
4
|
+
attr_accessor :object_name, :method
|
5
|
+
|
6
|
+
|
7
|
+
#
|
8
|
+
# Create a list of all of the current app's Active Record Models
|
9
|
+
# returns an array of hashes
|
10
|
+
#
|
11
|
+
def find_all_models
|
12
|
+
models = []
|
13
|
+
|
14
|
+
# iterate over all files in folder
|
15
|
+
folder = File.join(ValidationSync::Engine::APP_ROOT, "app", "models")
|
16
|
+
|
17
|
+
Dir[File.join(folder, "*")].each do |filename|
|
18
|
+
klass = File.basename(filename, '.rb').camelize.constantize
|
19
|
+
next unless klass.ancestors.include?(ActiveRecord::Base)
|
20
|
+
|
21
|
+
model = {
|
22
|
+
name: klass.name.downcase,
|
23
|
+
attributes: klass.new.attributes.keys
|
24
|
+
}
|
25
|
+
|
26
|
+
models << model
|
27
|
+
end
|
28
|
+
|
29
|
+
return models
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
|
34
|
+
#
|
35
|
+
# Check to see if a given model attribute uses a given validation
|
36
|
+
# returns either a validation object or nil
|
37
|
+
#
|
38
|
+
def get_model_validation(object_name=self.object_name, method=self.method, validation)
|
39
|
+
object_class = object_name.camelize.constantize
|
40
|
+
if val = object_class.validators_on(method).find { |v| v.class == validation }
|
41
|
+
val
|
42
|
+
else
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
#
|
50
|
+
# Check to see if a given model attribute uses a given validation
|
51
|
+
# returns true / false
|
52
|
+
#
|
53
|
+
def check_model_validation(object_name=self.object_name, method=self.method, validation)
|
54
|
+
unless get_model_validation(object_name, method, validation).nil?
|
55
|
+
return true
|
56
|
+
else
|
57
|
+
return false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
|
63
|
+
#
|
64
|
+
# Fetch a given option for a model's attribute's validation
|
65
|
+
# returns the specified validation option
|
66
|
+
#
|
67
|
+
def get_validation_attr(object_name=self.object_name, method=self.method, validation, option)
|
68
|
+
|
69
|
+
# Make sure that we use this validation for this attribute
|
70
|
+
if get_model_validation(object_name, method, validation)
|
71
|
+
|
72
|
+
# look up the option
|
73
|
+
object_class = object_name.camelize.constantize
|
74
|
+
validation = object_class.validators_on(method).find { |v| v.class == validation }
|
75
|
+
return (validation.options[option]) ? validation.options[option] : nil
|
76
|
+
|
77
|
+
else
|
78
|
+
nil
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
#
|
85
|
+
# Fetch the validation message for a given model's attribute's validation
|
86
|
+
# returns a string
|
87
|
+
#
|
88
|
+
def get_validation_message(object_name=self.object_name, method=self.method, validation)
|
89
|
+
|
90
|
+
unless (val = get_model_validation(object_name, method, validation)).nil?
|
91
|
+
|
92
|
+
if val.options[:message]
|
93
|
+
# Simple lookup:
|
94
|
+
return val.options[:message]
|
95
|
+
|
96
|
+
else
|
97
|
+
# Takes some digging:
|
98
|
+
# get the index of this validation in the validators_on array...
|
99
|
+
validators_array = []
|
100
|
+
|
101
|
+
object_class = object_name.camelize.constantize
|
102
|
+
object_class.validators_on(method).each do |v|
|
103
|
+
validators_array << v.class
|
104
|
+
end
|
105
|
+
|
106
|
+
validators_hash = Hash[validators_array.map.with_index.to_a]
|
107
|
+
index = validators_hash[validation]
|
108
|
+
|
109
|
+
# create a new object
|
110
|
+
object = object_class.new
|
111
|
+
|
112
|
+
# Do we need ro define a confirmation_of attribute?
|
113
|
+
# If so, then we should read the errors from this
|
114
|
+
# attribute, rather than the original
|
115
|
+
if object_class.method_defined?("#{method}_confirmation")
|
116
|
+
object.send("#{method}_confirmation=", "#{object.send(method)}_not_confirmed")
|
117
|
+
method_to_read_errors_from = "#{method}_confirmation".to_sym
|
118
|
+
else
|
119
|
+
method_to_read_errors_from = method
|
120
|
+
end
|
121
|
+
|
122
|
+
# gather the errors
|
123
|
+
object.valid?
|
124
|
+
|
125
|
+
# and match the index to the errors array
|
126
|
+
if object.errors.messages[method_to_read_errors_from]
|
127
|
+
return object.errors.messages[method_to_read_errors_from][index]
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
else
|
132
|
+
nil
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
|
139
|
+
end # ValidationBuilder
|
data/lib/validation_sync.rb
CHANGED
@@ -53,6 +53,6 @@ class PostsController < ApplicationController
|
|
53
53
|
|
54
54
|
# Only allow a trusted parameter "white list" through.
|
55
55
|
def post_params
|
56
|
-
params.require(:post).permit(:title, :content, :view_count, :author_email)
|
56
|
+
params.require(:post).permit(:title, :content, :view_count, :order, :author_email, :user_id)
|
57
57
|
end
|
58
58
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
class UsersController < ApplicationController
|
2
|
+
before_action :set_user, only: [:show, :edit, :update, :destroy]
|
3
|
+
|
4
|
+
# GET /users
|
5
|
+
def index
|
6
|
+
@users = User.all
|
7
|
+
end
|
8
|
+
|
9
|
+
# GET /users/1
|
10
|
+
def show
|
11
|
+
end
|
12
|
+
|
13
|
+
# GET /users/new
|
14
|
+
def new
|
15
|
+
@user = User.new
|
16
|
+
end
|
17
|
+
|
18
|
+
# GET /users/1/edit
|
19
|
+
def edit
|
20
|
+
end
|
21
|
+
|
22
|
+
# POST /users
|
23
|
+
def create
|
24
|
+
@user = User.new(user_params)
|
25
|
+
|
26
|
+
if @user.save
|
27
|
+
redirect_to @user, notice: 'User was successfully created.'
|
28
|
+
else
|
29
|
+
render action: 'new'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# PATCH/PUT /users/1
|
34
|
+
def update
|
35
|
+
if @user.update(user_params)
|
36
|
+
redirect_to @user, notice: 'User was successfully updated.'
|
37
|
+
else
|
38
|
+
render action: 'edit'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# DELETE /users/1
|
43
|
+
def destroy
|
44
|
+
@user.destroy
|
45
|
+
redirect_to users_url, notice: 'User was successfully destroyed.'
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
# Use callbacks to share common setup or constraints between actions.
|
50
|
+
def set_user
|
51
|
+
@user = User.find(params[:id])
|
52
|
+
end
|
53
|
+
|
54
|
+
# Only allow a trusted parameter "white list" through.
|
55
|
+
def user_params
|
56
|
+
params.require(:user).permit(:email, :password, :password_confirmation)
|
57
|
+
end
|
58
|
+
end
|
@@ -1,10 +1,21 @@
|
|
1
1
|
class Post < ActiveRecord::Base
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
validates_length_of :title, :minimum => 5
|
3
|
+
# Title
|
4
|
+
validates_presence_of :title, :message => "You need a title, bro."
|
5
|
+
validates_length_of :title, :minimum => 5
|
6
6
|
|
7
|
+
# View Count
|
7
8
|
validates_presence_of :view_count
|
8
|
-
validates_numericality_of :view_count
|
9
|
+
validates_numericality_of :view_count
|
10
|
+
|
11
|
+
# Order
|
12
|
+
validates_numericality_of :order, :message => "Make that shit a number!", :allow_nil => true
|
13
|
+
|
14
|
+
# User ID
|
15
|
+
validates_numericality_of :user_id, :message => "User ID Must be a number."
|
16
|
+
|
17
|
+
# Content
|
18
|
+
validates_presence_of :content
|
19
|
+
validates_length_of :content, :maximum => 140
|
9
20
|
|
10
21
|
end
|
@@ -23,10 +23,18 @@
|
|
23
23
|
<%= f.label :view_count %><br>
|
24
24
|
<%= f.text_field :view_count %>
|
25
25
|
</div>
|
26
|
+
<div class="field">
|
27
|
+
<%= f.label :order %><br>
|
28
|
+
<%= f.text_field :order %>
|
29
|
+
</div>
|
26
30
|
<div class="field">
|
27
31
|
<%= f.label :author_email %><br>
|
28
32
|
<%= f.text_field :author_email %>
|
29
33
|
</div>
|
34
|
+
<div class="field">
|
35
|
+
<%= f.label :user_id %><br>
|
36
|
+
<%= f.text_field :user_id %>
|
37
|
+
</div>
|
30
38
|
<div class="actions">
|
31
39
|
<%= f.submit %>
|
32
40
|
</div>
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<%= form_for(@user, :validate => true) do |f| %>
|
2
|
+
<% if @user.errors.any? %>
|
3
|
+
<div id="error_explanation">
|
4
|
+
<h2><%= pluralize(@user.errors.count, "error") %> prohibited this user from being saved:</h2>
|
5
|
+
|
6
|
+
<ul>
|
7
|
+
<% @user.errors.full_messages.each do |msg| %>
|
8
|
+
<li><%= msg %></li>
|
9
|
+
<% end %>
|
10
|
+
</ul>
|
11
|
+
</div>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<div class="field">
|
15
|
+
<%= f.label :email %><br>
|
16
|
+
<%= f.text_field :email %>
|
17
|
+
</div>
|
18
|
+
<div class="field">
|
19
|
+
<%= f.label :email_confirmation %><br>
|
20
|
+
<%= f.text_field :email_confirmation %>
|
21
|
+
</div>
|
22
|
+
<div class="field">
|
23
|
+
<%= f.label :password %><br>
|
24
|
+
<%= f.text_field :password %>
|
25
|
+
</div>
|
26
|
+
<div class="field">
|
27
|
+
<%= f.label :password_confirmation %><br>
|
28
|
+
<%= f.text_field :password_confirmation %>
|
29
|
+
</div>
|
30
|
+
<div class="actions">
|
31
|
+
<%= f.submit %>
|
32
|
+
</div>
|
33
|
+
<% end %>
|
@@ -0,0 +1,29 @@
|
|
1
|
+
<h1>Listing users</h1>
|
2
|
+
|
3
|
+
<table>
|
4
|
+
<thead>
|
5
|
+
<tr>
|
6
|
+
<th>Email</th>
|
7
|
+
<th>Password</th>
|
8
|
+
<th></th>
|
9
|
+
<th></th>
|
10
|
+
<th></th>
|
11
|
+
</tr>
|
12
|
+
</thead>
|
13
|
+
|
14
|
+
<tbody>
|
15
|
+
<% @users.each do |user| %>
|
16
|
+
<tr>
|
17
|
+
<td><%= user.email %></td>
|
18
|
+
<td><%= user.password %></td>
|
19
|
+
<td><%= link_to 'Show', user %></td>
|
20
|
+
<td><%= link_to 'Edit', edit_user_path(user) %></td>
|
21
|
+
<td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td>
|
22
|
+
</tr>
|
23
|
+
<% end %>
|
24
|
+
</tbody>
|
25
|
+
</table>
|
26
|
+
|
27
|
+
<br>
|
28
|
+
|
29
|
+
<%= link_to 'New User', new_user_path %>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<p id="notice"><%= notice %></p>
|
2
|
+
|
3
|
+
<p>
|
4
|
+
<strong>Email:</strong>
|
5
|
+
<%= @user.email %>
|
6
|
+
</p>
|
7
|
+
|
8
|
+
<p>
|
9
|
+
<strong>Password:</strong>
|
10
|
+
<%= @user.password %>
|
11
|
+
</p>
|
12
|
+
|
13
|
+
<%= link_to 'Edit', edit_user_path(@user) %> |
|
14
|
+
<%= link_to 'Back', users_path %>
|
data/spec/dummy/config/routes.rb
CHANGED
Binary file
|