validaform 0.1.1

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.
@@ -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: []