validaform 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3c005a5f1f3f8768545e904ac1ede42b8a6b5d03
4
+ data.tar.gz: fd1d19204dc5ffb31b88e59aed7a53bde37b0b0b
5
+ SHA512:
6
+ metadata.gz: ec7c2fb4e6ad31a228a0b4db06be35f27accacb73485b79b56eaad824768f7c8fc881da9d1fcd802761eb18f1f3ac906d967824dbce1f132d16ca7182f337c02
7
+ data.tar.gz: 84637f5e5ef55e6f4ff3d5652dd4eea47819baae1236e3e1231253c0f134db74af6f75d9f44f384df67a2515f5de536da3a4ae3a22a0b30a689690f3e365cbed
@@ -0,0 +1,20 @@
1
+ Copyright 2017 poilon
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.
@@ -0,0 +1,28 @@
1
+ # Validaform
2
+ Short description and motivation.
3
+
4
+ ## Usage
5
+ How to use my plugin.
6
+
7
+ ## Installation
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'validaform'
12
+ ```
13
+
14
+ And then execute:
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+ ```bash
21
+ $ gem install validaform
22
+ ```
23
+
24
+ ## Contributing
25
+ Contribution directions go here.
26
+
27
+ ## License
28
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -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
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Validaform'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+
21
+ load 'rails/tasks/statistics.rake'
22
+
23
+
24
+
25
+ require 'bundler/gem_tasks'
26
+
27
+ require 'rake/testtask'
28
+
29
+ Rake::TestTask.new(:test) do |t|
30
+ t.libs << 'test'
31
+ t.pattern = 'test/**/*_test.rb'
32
+ t.verbose = false
33
+ end
34
+
35
+
36
+ task default: :test
@@ -0,0 +1,7 @@
1
+ module Validaform
2
+ class ApplicationController < ActionController::Base
3
+
4
+ protect_from_forgery with: :exception
5
+
6
+ end
7
+ end
@@ -0,0 +1,16 @@
1
+ module Validaform
2
+ class FormsController < Validaform::ApplicationController
3
+
4
+ skip_before_action :verify_authenticity_token
5
+
6
+ # curl -X POST -H 'Content-Type: application/json' -d \
7
+ # '{"fields":[{"name":"users/first_name","value":"Asterix"},
8
+ # {"name":"users/last_name","value":"LeGaulois"}, {"name":"companies/size", "value":"17"}]}' \
9
+ # http://localhost:3000/validaform/forms/validate
10
+ def validate
11
+ validator = Validaform::Base.new(params: params)
12
+ render json: validator.errors, status: validator.status_code
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,9 @@
1
+ Validaform::Engine.routes.draw do
2
+
3
+ resources :forms do
4
+ collection do
5
+ post 'validate'
6
+ end
7
+ end
8
+
9
+ end
@@ -0,0 +1,128 @@
1
+ require 'validaform/engine'
2
+
3
+ module Validaform
4
+ class Base
5
+
6
+ attr_reader :fields
7
+ attr_accessor :status_code
8
+
9
+ def initialize(params:)
10
+ @fields = params.permit(fields: %i[name value]).to_h[:fields]
11
+ @status_code = 200
12
+ end
13
+
14
+ # fields =>
15
+ # [
16
+ # { name: 'users/first_name', value: 'Asterix' }
17
+ # ]
18
+ # errors will return
19
+ # {
20
+ # fields:[
21
+ # {
22
+ # name: 'users/first_name',
23
+ # errors: ['too_short', 'too_long'],
24
+ # count: 2
25
+ # }
26
+ # ],
27
+ # count: 2
28
+ # }
29
+ def errors
30
+ errors_hash = { fields: [] }
31
+ parse_fields.map do |resource, fields|
32
+ resource_class = resource_class(resource)
33
+ dev_errors = handle_development_errors(resource, resource_class, fields)
34
+ return dev_errors if dev_errors.present?
35
+ generate_errors_hash(resource, resource_class, fields, errors_hash)
36
+ end
37
+ errors_hash[:count] = total_errors_count(errors_hash)
38
+ errors_hash
39
+ end
40
+
41
+ private
42
+
43
+ # fields =>
44
+ # [
45
+ # { name: 'users/first_name', value: 'Asterix' },
46
+ # { name: 'users/last_name', value: 'LeGaulois' },
47
+ # { name: 'companies/name', value: 'PotionCorp' }
48
+ # ]
49
+ # parse_field transforms it to
50
+ #
51
+ # {
52
+ # users: {
53
+ # first_name: 'Asterix',
54
+ # last_name: 'LeGaulois'
55
+ # },
56
+ # companies: { name: 'PotionCorp' }
57
+ # }
58
+ def parse_fields
59
+ fields.each_with_object({}) do |f, h|
60
+ h[f[:name].split('/').first] ||= {}
61
+ h[f[:name].split('/').first][f[:name].split('/').last] = f[:value]
62
+ end
63
+ end
64
+
65
+ # Count the global errors count
66
+ def total_errors_count(errors_hash)
67
+ errors_hash[:fields].map { |h| h[:count] }.reduce(:+) || 0
68
+ end
69
+
70
+ # Get the model class of the given resource
71
+ # Ex:
72
+ # $ resource_class('users')
73
+ # => User
74
+ def resource_class(resource)
75
+ resource.classify.constantize
76
+ rescue NameError
77
+ nil
78
+ end
79
+
80
+ def generate_errors_hash(resource, resource_class, fields, errors_hash)
81
+ # Create an instance of it and check if valid with the given attributes
82
+ fetch_object(fields, resource_class).tap(&:valid?).errors.messages.each do |field, errors|
83
+ next unless fields.keys.include?(field.to_s)
84
+ errors_hash[:fields] << {
85
+ name: "#{resource}/#{field}", errors: errors, count: errors.count
86
+ }
87
+ end
88
+ end
89
+
90
+ def fetch_object(fields, resource_class)
91
+ return resource_class.new(fields) if fields['id'].blank?
92
+ resource_class.find_by(id: fields['id']).tap { |r| r.attributes = fields }
93
+ end
94
+
95
+ def handle_development_errors(resource, klass, fields)
96
+ return not_defined_class_error(resource) if klass.nil?
97
+ return not_db_model_error(resource) unless klass.ancestors.include?(ApplicationRecord)
98
+ invalid_fields = fields.keys - klass.new.attributes.keys
99
+ return invalid_fields_error(invalid_fields) if invalid_fields.present?
100
+ return object_not_found_error(resource) if fields['id'] && !klass.find_by(id: fields['id'])
101
+ nil
102
+ end
103
+
104
+ def object_not_found_error(resource)
105
+ @status_code = 400
106
+ { code: 'RESOURCE NOT FOUND', message: "#{resource} not found on database" }
107
+ end
108
+
109
+ def not_defined_class_error(resource)
110
+ @status_code = 400
111
+ { code: 'INVALID RESOURCE', message: "#{resource} is not a valid resource" }
112
+ end
113
+
114
+ def form_errors_handler(resource)
115
+ @status_code = 400
116
+ { code: 'NOT A DB MODEL', message: "#{resource} is not a DB model" }
117
+ end
118
+
119
+ def invalid_fields_error(invalid_fields)
120
+ @status_code = 400
121
+ {
122
+ code: 'INVALID FIELDS',
123
+ message: "\"#{invalid_fields.join(', ')}\" aren't valid model fields"
124
+ }
125
+ end
126
+
127
+ end
128
+ end
@@ -0,0 +1,5 @@
1
+ module Validaform
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace Validaform
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module Validaform
2
+ VERSION = '0.1.1'.freeze
3
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: validaform
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - poilon
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-05-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '5.1'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 5.1.1
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '5.1'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 5.1.1
33
+ description: Mount to an endpoint of your application, give it forms fields, and it'll
34
+ return the validations errors/success in JSON. Really usefull when you want to add
35
+ on-unblur or before-submit validations.
36
+ email:
37
+ - poilon@gmail.com
38
+ executables: []
39
+ extensions: []
40
+ extra_rdoc_files: []
41
+ files:
42
+ - MIT-LICENSE
43
+ - README.md
44
+ - Rakefile
45
+ - app/controllers/validaform/application_controller.rb
46
+ - app/controllers/validaform/forms_controller.rb
47
+ - config/routes.rb
48
+ - lib/validaform.rb
49
+ - lib/validaform/engine.rb
50
+ - lib/validaform/version.rb
51
+ homepage: https://github.com/Poilon/validaform
52
+ licenses:
53
+ - MIT
54
+ metadata: {}
55
+ post_install_message:
56
+ rdoc_options: []
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ requirements: []
70
+ rubyforge_project:
71
+ rubygems_version: 2.6.10
72
+ signing_key:
73
+ specification_version: 4
74
+ summary: Perform a validation for forms via API call
75
+ test_files: []