ajax_validator 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +87 -0
- data/Rakefile +36 -0
- data/app/assets/javascripts/ajax_validator/ajax_validator.js.coffee +46 -0
- data/app/assets/javascripts/ajax_validator/application.js +13 -0
- data/app/assets/stylesheets/ajax_validator/application.css +15 -0
- data/app/controllers/ajax_validator/application_controller.rb +4 -0
- data/app/controllers/ajax_validator/validators_controller.rb +68 -0
- data/app/helpers/ajax_validator/application_helper.rb +4 -0
- data/app/models/ajax_validator/concerns/validation.rb +21 -0
- data/app/models/ajax_validator/validator.rb +128 -0
- data/app/views/layouts/ajax_validator/application.html.erb +14 -0
- data/config/cucumber.yml +8 -0
- data/config/routes.rb +3 -0
- data/lib/ajax_validator/engine.rb +42 -0
- data/lib/ajax_validator/version.rb +3 -0
- data/lib/ajax_validator.rb +4 -0
- data/lib/tasks/ajax_validator_tasks.rake +4 -0
- data/lib/tasks/cucumber.rake +65 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/base_controller.rb +5 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +29 -0
- data/spec/dummy/config/application.rb +32 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +110 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +41 -0
- data/spec/dummy/config/environments/production.rb +79 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/assets.rb +11 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +4 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +715 -0
- data/spec/dummy/log/test.log +294 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/rails_helper.rb +68 -0
- data/spec/route_helper.rb +6 -0
- data/spec/spec_helper.rb +99 -0
- data/spec/support/capybara.rb +35 -0
- data/spec/support/database_cleaner.rb +77 -0
- data/spec/support/factory_girl_rails.rb +32 -0
- data/spec/support/matchers.rb +21 -0
- metadata +408 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7ea11a9a26ae42ec77a8b1513400c90c09299e53
|
4
|
+
data.tar.gz: 39a0f8bb6725c27919e8eba0534585c816bddc1e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6bf4253121c5c57cd0590f7f7a9c3d6c767195a1831523d9e7615224d456e186c768ff9063e1396e3d93f0069be3b4cb4c156d8b238ab7eb58dec90f43661349
|
7
|
+
data.tar.gz: dc01803395572d253fd2e0d86b52fd38f59d5530759c84222271e78d520bccf40b102d1f976f2a968774f45d89cc0b6235828be57788a7214c691109d5b415e1
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2016 efigence
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
# Ajax Validator [![Build Status](https://travis-ci.org/efigence/ajax_validator.svg?branch=master)](http://travis-ci.org/efigence/ajax_validator)
|
2
|
+
|
3
|
+
### Ajax Live Form Validation Rails Engine
|
4
|
+
|
5
|
+
## How to install
|
6
|
+
|
7
|
+
1. Add to `Gemfile`
|
8
|
+
|
9
|
+
gem 'ajax_validator', path: 'vendor/engines/ajax_validator'
|
10
|
+
2. Bundle
|
11
|
+
|
12
|
+
bundle install
|
13
|
+
3. Create file `config/initializers/ajax_validator.rb` and specify validatable models
|
14
|
+
|
15
|
+
AjaxValidator::Engine.setup do |config|
|
16
|
+
config.ajax_validator_engine = {
|
17
|
+
# if form object is used, both classes must be put here
|
18
|
+
whitelist_models: ['some_klass', 'some_module/some_klass']
|
19
|
+
}
|
20
|
+
end
|
21
|
+
4. Copy migration (currently, not needed)
|
22
|
+
|
23
|
+
bundle exec rake ajax_validator:install:migrations
|
24
|
+
5. Run migration (currently, not needed)
|
25
|
+
|
26
|
+
bundle exec rake db:migrate SCOPE=ajax_validator
|
27
|
+
6. Run seeds (currently, not needed)
|
28
|
+
|
29
|
+
bundle exec rake ajax_validator:db:seed
|
30
|
+
7. Add to `config/routes.rb`
|
31
|
+
|
32
|
+
mount AjaxValidator::Engine, at: '/ajax_validator'
|
33
|
+
|
34
|
+
## How to use helpers
|
35
|
+
|
36
|
+
Include the needed javascript file in your application.js or application.js.coffee
|
37
|
+
|
38
|
+
Javascript
|
39
|
+
//= require ajax_validator/application
|
40
|
+
|
41
|
+
or CoffeeScript
|
42
|
+
#= require ajax_validator/application
|
43
|
+
|
44
|
+
Script will add class 'has-error' or 'has-success' to the field wrapping div, based on the result.
|
45
|
+
|
46
|
+
Add these attributes on text input field:
|
47
|
+
class: 'ajax_validator__field'
|
48
|
+
data-form-object='validations/signup_form_company_name' [Optional, leave empty string '' validate on model directly]
|
49
|
+
data-resource-model='company'
|
50
|
+
data-resource-attr-name='name'
|
51
|
+
data-ignore-resource-attr-value='false' [Optional, set to 'true' when attribute is assembled from additional params instead]
|
52
|
+
data-resource-instance-additional-params='{"something": true, "something_else": ""}' [Optional]
|
53
|
+
|
54
|
+
Example on Bootstrap:
|
55
|
+
|
56
|
+
ERB:
|
57
|
+
<div class="input-group">
|
58
|
+
<input class='form-control ajax_validator__field' data-form-object='validations/signup_form_company_name' data-resource-model='company' data-resource-attr-name='name' type='text' name='signup_form[company]' id='signup_form_company'>
|
59
|
+
</div>
|
60
|
+
|
61
|
+
or HAML:
|
62
|
+
.input-group
|
63
|
+
= f.text_field :company, class: 'form-control ajax_validator__field', data: {form_object: 'validations/signup_form_company_name', resource_model: 'company', resource_attr_name: 'name'}
|
64
|
+
|
65
|
+
### How to add a new gem to the engine
|
66
|
+
- Add a gem to `Gemfile`
|
67
|
+
- Run: `bundle`
|
68
|
+
- Copy over to multiple gemfiles: `bundle exec appraisal install`
|
69
|
+
|
70
|
+
### How to test
|
71
|
+
cd vendor/engines/ajax_validator/
|
72
|
+
export DATABASE_URL='postgres://localhost:5432' AJAX_VALIDATOR_DATABASE_USERNAME=postgres AJAX_VALIDATOR_DATABASE_PASSWORD=p
|
73
|
+
|
74
|
+
bundle exec appraisal rails-4.1 rake db:create db:migrate db:seed
|
75
|
+
---
|
76
|
+
- Optional:
|
77
|
+
|
78
|
+
bundle exec appraisal rails-4.1 rake db:schema:load RAILS_ENV=test
|
79
|
+
---
|
80
|
+
|
81
|
+
bundle exec appraisal rails-4.1 rake spec
|
82
|
+
bundle exec appraisal rails-4.1 rake app:cucumber
|
83
|
+
|
84
|
+
## How to develop
|
85
|
+
bundle exec rails g scaffold Post name:string --integration_tool=rspec --helper=false --assets=false
|
86
|
+
bundle exec rails g cucumber_scaffold:feature Post name:string
|
87
|
+
bundle exec rails db:migrate
|
data/Rakefile
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
8
|
+
load 'rails/tasks/engine.rake'
|
9
|
+
|
10
|
+
#load 'rails/tasks/statistics.rake'
|
11
|
+
|
12
|
+
Bundler::GemHelper.install_tasks
|
13
|
+
|
14
|
+
Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each {|f| load f }
|
15
|
+
require 'rspec/core'
|
16
|
+
require 'rspec/core/rake_task'
|
17
|
+
require 'appraisal'
|
18
|
+
|
19
|
+
task :default => :spec
|
20
|
+
|
21
|
+
# RSpec::Core::RakeTask.new(:spec)
|
22
|
+
RSpec::Core::RakeTask.new(:spec => 'app:db:test:prepare')
|
23
|
+
|
24
|
+
desc 'Default'
|
25
|
+
task :default do
|
26
|
+
if ENV['BUNDLE_GEMFILE'] =~ /gemfiles/
|
27
|
+
#Rake::Task['app:db:test:prepare'].invoke
|
28
|
+
Rake::Task['spec'].invoke
|
29
|
+
else
|
30
|
+
Rake::Task['appraise'].invoke
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
task :appraise do
|
35
|
+
exec 'appraisal install && appraisal rake'
|
36
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
window.ajax_validator_timeout = undefined
|
2
|
+
|
3
|
+
$(document).on 'ready', (_event) ->
|
4
|
+
$('form').on 'keydown', '.ajax_validator__field', (e) ->
|
5
|
+
|
6
|
+
form_object = $(@).data('form-object')
|
7
|
+
resource_model = $(@).data('resource-model')
|
8
|
+
resource_attr_name = $(@).data('resource-attr-name')
|
9
|
+
ignore_resource_attr_value = $(@).data('ignore-resource-attr-value')
|
10
|
+
resource_instance_additional_params = $(@).data('resource-instance-additional-params')
|
11
|
+
|
12
|
+
queue_id = form_object + '-' + resource_model + resource_attr_name
|
13
|
+
|
14
|
+
$(document).queue queue_id, (next) =>
|
15
|
+
|
16
|
+
parent_div = $(@).parents('div').eq(0)
|
17
|
+
resource_attr_value = $(@).val()
|
18
|
+
|
19
|
+
$.ajax
|
20
|
+
url: "/ajax_validator/validators"
|
21
|
+
type: "POST"
|
22
|
+
dataType: "json"
|
23
|
+
data:
|
24
|
+
'validator':
|
25
|
+
'form_object': form_object
|
26
|
+
'resource_model': resource_model
|
27
|
+
'resource_attr_name': resource_attr_name
|
28
|
+
'resource_attr_value': resource_attr_value
|
29
|
+
'ignore_resource_attr_value': ignore_resource_attr_value
|
30
|
+
'resource_instance_additional_params': resource_instance_additional_params
|
31
|
+
success: (returnData) ->
|
32
|
+
if parent_div
|
33
|
+
if returnData['errors'].length > 0
|
34
|
+
$(parent_div).removeClass("has-error has-success").addClass("has-error")
|
35
|
+
else
|
36
|
+
$(parent_div).removeClass("has-error has-success").addClass("has-success")
|
37
|
+
else
|
38
|
+
$('body').html(JSON.stringify returnData)
|
39
|
+
error: (e) ->
|
40
|
+
# console.log(JSON.stringify e)
|
41
|
+
|
42
|
+
clearTimeout(ajax_validator_timeout);
|
43
|
+
|
44
|
+
window.ajax_validator_timeout = setTimeout((->
|
45
|
+
$(document).dequeue queue_id
|
46
|
+
), 1000)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require_tree .
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any styles
|
10
|
+
* defined in the other CSS/SCSS files in this directory. It is generally better to create a new
|
11
|
+
* file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require_dependency 'ajax_validator/application_controller'
|
2
|
+
|
3
|
+
module AjaxValidator
|
4
|
+
class ValidatorsController < ApplicationController
|
5
|
+
skip_before_action :verify_authenticity_token, only: [:create]
|
6
|
+
|
7
|
+
# POST /validators
|
8
|
+
#
|
9
|
+
# {
|
10
|
+
# 'validator': {
|
11
|
+
# 'form_object': 'validations/signup_form_company_name',
|
12
|
+
# 'resource_model': 'company'
|
13
|
+
# 'resource_attr_name': 'name',
|
14
|
+
# 'resource_attr_value': 'Efigence'
|
15
|
+
# }
|
16
|
+
# }
|
17
|
+
#
|
18
|
+
# or:
|
19
|
+
#
|
20
|
+
# {
|
21
|
+
# 'validator': {
|
22
|
+
# 'form_object': '',
|
23
|
+
# 'resource_model': 'company'
|
24
|
+
# 'resource_attr_name': 'name',
|
25
|
+
# 'resource_attr_value': 'Efigence'
|
26
|
+
# }
|
27
|
+
# }
|
28
|
+
#
|
29
|
+
# Response (jsonapi.org format)
|
30
|
+
#
|
31
|
+
# on success:
|
32
|
+
#
|
33
|
+
# {
|
34
|
+
# 'errors': []
|
35
|
+
# }
|
36
|
+
#
|
37
|
+
# on failure:
|
38
|
+
#
|
39
|
+
# {
|
40
|
+
# 'errors': [
|
41
|
+
# {
|
42
|
+
# 'name': [
|
43
|
+
# 'has already been taken'
|
44
|
+
# ]
|
45
|
+
# }
|
46
|
+
# ]
|
47
|
+
# }
|
48
|
+
def create
|
49
|
+
validated = Validator.new(validator_params).validate
|
50
|
+
response = { 'errors' => validated.errors.messages.stringify_keys.map{|i| {i[0] => i[1]}} }
|
51
|
+
render json: response.to_json
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
# Only allow a trusted parameter 'white list' through.
|
57
|
+
def validator_params
|
58
|
+
wildcard = params.try(:[], :validator).try(:[], :resource_instance_additional_params).try(:keys)
|
59
|
+
params.require(:validator).
|
60
|
+
permit(:form_object,
|
61
|
+
:resource_model,
|
62
|
+
:resource_attr_name,
|
63
|
+
:resource_attr_value,
|
64
|
+
:ignore_resource_attr_value,
|
65
|
+
:resource_instance_additional_params => wildcard)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module AjaxValidator
|
2
|
+
module Concerns
|
3
|
+
module Validation
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
included do
|
6
|
+
private
|
7
|
+
def ajax_validator_valid_attribute?(resource_attr_name, resource_attr_value, model_instance = self)
|
8
|
+
model_instance.class.validators_on(resource_attr_name.to_sym).each do |validator|
|
9
|
+
if validator.options[:if]
|
10
|
+
next unless !!model_instance.send(validator.options[:if])
|
11
|
+
end
|
12
|
+
if validator.options[:unless]
|
13
|
+
next if !!model_instance.send(validator.options[:unless])
|
14
|
+
end
|
15
|
+
validator.validate_each(model_instance, resource_attr_name.to_sym, resource_attr_value)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
# Use with form object that responds to `validate` method,
|
2
|
+
# e.g. use Reform or Virtus with ActiveModel::Validations
|
3
|
+
#
|
4
|
+
# Open the console and try:
|
5
|
+
#
|
6
|
+
# validator_params = { form_object: 'validations/signup_form_company_name',
|
7
|
+
# resource_model: 'company',
|
8
|
+
# resource_attr_name: 'name',
|
9
|
+
# resource_attr_value: 'Efigence' }
|
10
|
+
#
|
11
|
+
# One can use the engine with any ActiveModel::Model object with ActiveModel::Validations
|
12
|
+
# included. For performance, even if the model is clobbered with validations, only validations
|
13
|
+
# on the specified field one will be fired. Examples:
|
14
|
+
#
|
15
|
+
# validator_params = { form_object: '',
|
16
|
+
# resource_model: 'company',
|
17
|
+
# resource_attr_name: 'name',
|
18
|
+
# resource_attr_value: 'efigence' }
|
19
|
+
#
|
20
|
+
# Validate (also conditionally) virtual or model attribute set inside some before validation callback:
|
21
|
+
#
|
22
|
+
# validator_params = { form_object: '',
|
23
|
+
# resource_model: 'company',
|
24
|
+
# resource_attr_name: 'vat_number_with_prefix',
|
25
|
+
# resource_attr_value: '',
|
26
|
+
# ignore_resource_attr_value: 'true',
|
27
|
+
# resource_instance_additional_params: {country: 'Poland',
|
28
|
+
# vat_number: '0123456789'} }
|
29
|
+
#
|
30
|
+
# validator_params = { form_object: '',
|
31
|
+
# resource_model: 'company',
|
32
|
+
# resource_attr_name: 'vat_number',
|
33
|
+
# resource_attr_value: '',
|
34
|
+
# ignore_resource_attr_value: 'true',
|
35
|
+
# resource_instance_additional_params: {business_owner: true,
|
36
|
+
# vat_number: ''} }
|
37
|
+
#
|
38
|
+
# validator = AjaxValidator::Validator.new(validator_params)
|
39
|
+
# tested_company = validator.validate
|
40
|
+
# tested_company.errors.to_a
|
41
|
+
#
|
42
|
+
# - `resource_instance_additional_params` hash is passed as args to given active model instance,
|
43
|
+
# to handle before validation callbacks' dependencies, however, if form object is used,
|
44
|
+
# additional params - if specified - must be handled by form object instance itself,
|
45
|
+
# implementations may vary.
|
46
|
+
# - set `ignore_resource_attr_value` to 'true' if attribute value is assembled inside before validation
|
47
|
+
# callback
|
48
|
+
# - validating virtual attributes, custom validation methods and custom validators are all supported
|
49
|
+
module AjaxValidator
|
50
|
+
class Validator
|
51
|
+
|
52
|
+
def initialize(params = {})
|
53
|
+
@form_object = params[:form_object] # optional
|
54
|
+
@resource_model = params[:resource_model]
|
55
|
+
@resource_attr_name = params[:resource_attr_name]
|
56
|
+
@resource_attr_value = params[:resource_attr_value]
|
57
|
+
# skip setter if attribute is being assembled inside before validation callback
|
58
|
+
@ignore_resource_attr_value = params[:ignore_resource_attr_value].to_s == 'true'
|
59
|
+
if params[:resource_instance_additional_params].present?
|
60
|
+
@resource_instance_additional_params = params[:resource_instance_additional_params]
|
61
|
+
end
|
62
|
+
@bypass_whitelist = false
|
63
|
+
end
|
64
|
+
|
65
|
+
attr_accessor :form_object, :resource_model, :resource_attr_name, :resource_attr_value, :resource_instance_additional_params, :ignore_resource_attr_value, :bypass_whitelist
|
66
|
+
|
67
|
+
def validate
|
68
|
+
form_object_klass, resource_model_klass = safely_constantized_klasses
|
69
|
+
if form_object_klass
|
70
|
+
validate_form_object(resource_model_klass, form_object_klass)
|
71
|
+
else
|
72
|
+
validate_resource_model(resource_model_klass)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def safely_constantized_klasses
|
79
|
+
if form_object.present?
|
80
|
+
guard_whitelist(form_object)
|
81
|
+
form_object_klass = constantize_klass(form_object)
|
82
|
+
else
|
83
|
+
form_object_klass = nil
|
84
|
+
end
|
85
|
+
guard_whitelist(resource_model)
|
86
|
+
resource_model_klass = constantize_klass(resource_model)
|
87
|
+
[form_object_klass, resource_model_klass]
|
88
|
+
end
|
89
|
+
|
90
|
+
def constantize_klass(klass)
|
91
|
+
klass.to_s.classify.constantize
|
92
|
+
end
|
93
|
+
|
94
|
+
def validate_form_object(resource_model_klass, form_object_klass)
|
95
|
+
if resource_instance_additional_params
|
96
|
+
resource_instance = resource_model_klass.new(resource_instance_additional_params)
|
97
|
+
else
|
98
|
+
resource_instance = resource_model_klass.new
|
99
|
+
end
|
100
|
+
# support composition
|
101
|
+
klass_object = form_object_klass.new(resource_model.to_s => resource_instance) rescue nil
|
102
|
+
klass_object ||= form_object_klass.new(resource_instance)
|
103
|
+
klass_object.validate(resource_attr_name.to_s => resource_attr_value.to_s)
|
104
|
+
klass_object
|
105
|
+
end
|
106
|
+
|
107
|
+
def validate_resource_model(resource_model_klass)
|
108
|
+
klass_object = resource_model_klass.new(resource_instance_additional_params)
|
109
|
+
# run before_validation callback for active model (https://github.com/rails/rails/issues/718#issuecomment-1170499)
|
110
|
+
klass_object.try(:run_callbacks, :validation) { false }
|
111
|
+
if ignore_resource_attr_value
|
112
|
+
klass_object.send(:ajax_validator_valid_attribute?, resource_attr_name.to_s, klass_object.try(:send, resource_attr_name))
|
113
|
+
else
|
114
|
+
klass_object.send(:ajax_validator_valid_attribute?, resource_attr_name.to_s, resource_attr_value.to_s)
|
115
|
+
end
|
116
|
+
klass_object
|
117
|
+
end
|
118
|
+
|
119
|
+
def guard_whitelist(object)
|
120
|
+
unless bypass_whitelist
|
121
|
+
unless AjaxValidator::Engine.config[:whitelist_klasses].to_a.map{|i| i.to_s.underscore}.include?(object.to_s.underscore)
|
122
|
+
raise 'Class was not whitelisted!'
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>AjaxValidator</title>
|
5
|
+
<%= stylesheet_link_tag "ajax_validator/application", media: "all" %>
|
6
|
+
<%= javascript_include_tag "ajax_validator/application" %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
|
11
|
+
<%= yield %>
|
12
|
+
|
13
|
+
</body>
|
14
|
+
</html>
|
data/config/cucumber.yml
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
<%
|
2
|
+
rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
|
3
|
+
rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}"
|
4
|
+
std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} --strict --tags ~@wip"
|
5
|
+
%>
|
6
|
+
default: <%= std_opts %> features
|
7
|
+
wip: --tags @wip:3 --wip features
|
8
|
+
rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip
|
data/config/routes.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
module AjaxValidator
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
isolate_namespace AjaxValidator
|
4
|
+
|
5
|
+
config.generators do |g|
|
6
|
+
g.test_framework :rspec, :fixture => false
|
7
|
+
g.fixture_replacement :factory_girl, :dir => 'spec/factories'
|
8
|
+
end
|
9
|
+
|
10
|
+
config.to_prepare do
|
11
|
+
Rails.application.config.try(:ajax_validator_engine).try(:[], :whitelist_klasses).to_a.each do |whitelist_klass|
|
12
|
+
begin
|
13
|
+
klass = whitelist_klass.to_s.classify.constantize
|
14
|
+
rescue
|
15
|
+
raise "Can\'t constantize from \'#{whitelist_klass}\'. Check if class exists."
|
16
|
+
end
|
17
|
+
klass.include AjaxValidator::Concerns::Validation
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.setup(&block)
|
22
|
+
@@config ||= AjaxValidator::Engine::Configuration.new
|
23
|
+
yield @@config if block
|
24
|
+
return @@config
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.config
|
28
|
+
puts 'WARNING: ajax_validator_engine not configured' unless Rails.application.config.try(:ajax_validator_engine)
|
29
|
+
Rails.application.config.ajax_validator_engine
|
30
|
+
end
|
31
|
+
|
32
|
+
# will not reload in development
|
33
|
+
#initializer :prepare_models_for_ajax_validator do |app|
|
34
|
+
#end
|
35
|
+
|
36
|
+
#config.to_prepare do
|
37
|
+
# Dir.glob(Rails.root + "app/decorators/**/*_decorator*.rb").each do |c|
|
38
|
+
# require_dependency(c)
|
39
|
+
# end
|
40
|
+
#end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril.
|
2
|
+
# It is recommended to regenerate this file in the future when you upgrade to a
|
3
|
+
# newer version of cucumber-rails. Consider adding your own code to a new file
|
4
|
+
# instead of editing this one. Cucumber will automatically load all features/**/*.rb
|
5
|
+
# files.
|
6
|
+
|
7
|
+
|
8
|
+
unless ARGV.any? {|a| a =~ /^gems/} # Don't load anything when running the gems:* tasks
|
9
|
+
|
10
|
+
vendored_cucumber_bin = Dir["#{Rails.root}/vendor/{gems,plugins}/cucumber*/bin/cucumber"].first
|
11
|
+
$LOAD_PATH.unshift(File.dirname(vendored_cucumber_bin) + '/../lib') unless vendored_cucumber_bin.nil?
|
12
|
+
|
13
|
+
begin
|
14
|
+
require 'cucumber/rake/task'
|
15
|
+
|
16
|
+
namespace :cucumber do
|
17
|
+
Cucumber::Rake::Task.new({:ok => 'db:test:prepare'}, 'Run features that should pass') do |t|
|
18
|
+
t.binary = vendored_cucumber_bin # If nil, the gem's binary is used.
|
19
|
+
t.fork = true # You may get faster startup if you set this to false
|
20
|
+
t.profile = 'default'
|
21
|
+
end
|
22
|
+
|
23
|
+
Cucumber::Rake::Task.new({:wip => 'db:test:prepare'}, 'Run features that are being worked on') do |t|
|
24
|
+
t.binary = vendored_cucumber_bin
|
25
|
+
t.fork = true # You may get faster startup if you set this to false
|
26
|
+
t.profile = 'wip'
|
27
|
+
end
|
28
|
+
|
29
|
+
Cucumber::Rake::Task.new({:rerun => 'db:test:prepare'}, 'Record failing features and run only them if any exist') do |t|
|
30
|
+
t.binary = vendored_cucumber_bin
|
31
|
+
t.fork = true # You may get faster startup if you set this to false
|
32
|
+
t.profile = 'rerun'
|
33
|
+
end
|
34
|
+
|
35
|
+
desc 'Run all features'
|
36
|
+
task :all => [:ok, :wip]
|
37
|
+
|
38
|
+
task :statsetup do
|
39
|
+
require 'rails/code_statistics'
|
40
|
+
::STATS_DIRECTORIES << %w(Cucumber\ features features) if File.exist?('features')
|
41
|
+
::CodeStatistics::TEST_TYPES << "Cucumber features" if File.exist?('features')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
desc 'Alias for cucumber:ok'
|
45
|
+
task :cucumber => 'cucumber:ok'
|
46
|
+
|
47
|
+
task :default => :cucumber
|
48
|
+
|
49
|
+
task :features => :cucumber do
|
50
|
+
STDERR.puts "*** The 'features' task is deprecated. See rake -T cucumber ***"
|
51
|
+
end
|
52
|
+
|
53
|
+
# In case we don't have ActiveRecord, append a no-op task that we can depend upon.
|
54
|
+
task 'db:test:prepare' do
|
55
|
+
end
|
56
|
+
|
57
|
+
task :stats => 'cucumber:statsetup'
|
58
|
+
rescue LoadError
|
59
|
+
desc 'cucumber rake task not available (cucumber not installed)'
|
60
|
+
task :cucumber do
|
61
|
+
abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
== README
|
2
|
+
|
3
|
+
This README would normally document whatever steps are necessary to get the
|
4
|
+
application up and running.
|
5
|
+
|
6
|
+
Things you may want to cover:
|
7
|
+
|
8
|
+
* Ruby version
|
9
|
+
|
10
|
+
* System dependencies
|
11
|
+
|
12
|
+
* Configuration
|
13
|
+
|
14
|
+
* Database creation
|
15
|
+
|
16
|
+
* Database initialization
|
17
|
+
|
18
|
+
* How to run the test suite
|
19
|
+
|
20
|
+
* Services (job queues, cache servers, search engines, etc.)
|
21
|
+
|
22
|
+
* Deployment instructions
|
23
|
+
|
24
|
+
* ...
|
25
|
+
|
26
|
+
|
27
|
+
Please feel free to use a different markup language if you do not plan to run
|
28
|
+
<tt>rake doc:app</tt>.
|
data/spec/dummy/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require_tree .
|