form_core_v1 0.0.14
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 +97 -0
- data/Rakefile +34 -0
- data/lib/form_core.rb +48 -0
- data/lib/form_core/coder.rb +43 -0
- data/lib/form_core/coders/hash_coder.rb +19 -0
- data/lib/form_core/coders/yaml_coder.rb +43 -0
- data/lib/form_core/concerns/models/field.rb +72 -0
- data/lib/form_core/concerns/models/form.rb +38 -0
- data/lib/form_core/engine.rb +7 -0
- data/lib/form_core/errors.rb +12 -0
- data/lib/form_core/version.rb +5 -0
- data/lib/form_core/virtual_model.rb +77 -0
- data/lib/tasks/form_core_tasks.rake +5 -0
- metadata +88 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 87a636a0d0d56a208122563acd0ef6d26a6a00fe
|
4
|
+
data.tar.gz: 70c4bd33de24eb514df38432678be77e21a9f567
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 36cb5e15b9fa07d70ff05c5731f9d0c9dc902581d436e0252dd7e78468876df4471d369e82a2554527cf189e32028b6d6b166eb9f8461a53ebea93fe88e77a2c
|
7
|
+
data.tar.gz: 93bc33f7b006822a1d09da402af63b4b5d778a4d6cb1102e569ecaa6d45260bc51a3049a2dbd7254de6d5b49e60845954c1568dd8588d592186aef2a53e5a032
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2017 Jun Jiang
|
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,97 @@
|
|
1
|
+
Form Core
|
2
|
+
====
|
3
|
+
|
4
|
+
A Rails engine providing ability to generate dynamic form.
|
5
|
+
|
6
|
+
## Requirements
|
7
|
+
|
8
|
+
- MRI 2.3+
|
9
|
+
- Rails 5.0+
|
10
|
+
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
See demo for now.
|
14
|
+
|
15
|
+
## Installation
|
16
|
+
|
17
|
+
Add this line to your Gemfile:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
gem 'form_core'
|
21
|
+
```
|
22
|
+
|
23
|
+
Or you may want to include the gem directly from GitHub:
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
gem 'form_core', github: 'jasl-lab/form_core'
|
27
|
+
```
|
28
|
+
|
29
|
+
And then execute:
|
30
|
+
|
31
|
+
```sh
|
32
|
+
$ bundle
|
33
|
+
```
|
34
|
+
|
35
|
+
Copy migrations
|
36
|
+
|
37
|
+
```sh
|
38
|
+
$ bin/rails form_core:install:migrations
|
39
|
+
```
|
40
|
+
|
41
|
+
Then do migrate
|
42
|
+
|
43
|
+
```sh
|
44
|
+
$ bin/rails db:migrate
|
45
|
+
```
|
46
|
+
|
47
|
+
## Demo
|
48
|
+
|
49
|
+
Clone the repository.
|
50
|
+
|
51
|
+
```sh
|
52
|
+
$ git clone https://github.com/jasl-lab/form_core.git
|
53
|
+
```
|
54
|
+
|
55
|
+
Change directory
|
56
|
+
|
57
|
+
```sh
|
58
|
+
$ cd form_core
|
59
|
+
```
|
60
|
+
|
61
|
+
Run bundler
|
62
|
+
|
63
|
+
```sh
|
64
|
+
$ bundle install
|
65
|
+
```
|
66
|
+
|
67
|
+
Preparing database
|
68
|
+
|
69
|
+
```sh
|
70
|
+
$ bin/rails db:migrate
|
71
|
+
```
|
72
|
+
|
73
|
+
Start the Rails server
|
74
|
+
|
75
|
+
```sh
|
76
|
+
$ bin/rails s
|
77
|
+
```
|
78
|
+
|
79
|
+
Open your browser, and visit `http://localhost:3000`
|
80
|
+
|
81
|
+
## Contributing
|
82
|
+
|
83
|
+
Bug report or pull request are welcome.
|
84
|
+
|
85
|
+
### Make a pull request
|
86
|
+
|
87
|
+
1. Fork it
|
88
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
89
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
90
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
91
|
+
5. Create new Pull Request
|
92
|
+
|
93
|
+
Please write unit test with your code if necessary.
|
94
|
+
|
95
|
+
## License
|
96
|
+
|
97
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
begin
|
4
|
+
require "bundler/setup"
|
5
|
+
rescue LoadError
|
6
|
+
puts "You must `gem install bundler` and `bundle install` to run rake tasks"
|
7
|
+
end
|
8
|
+
|
9
|
+
require "rdoc/task"
|
10
|
+
|
11
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
12
|
+
rdoc.rdoc_dir = "rdoc"
|
13
|
+
rdoc.title = "FormCore"
|
14
|
+
rdoc.options << "--line-numbers"
|
15
|
+
rdoc.rdoc_files.include("README.md")
|
16
|
+
rdoc.rdoc_files.include("lib/**/*.rb")
|
17
|
+
end
|
18
|
+
|
19
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
20
|
+
load "rails/tasks/engine.rake"
|
21
|
+
|
22
|
+
load "rails/tasks/statistics.rake"
|
23
|
+
|
24
|
+
require "bundler/gem_tasks"
|
25
|
+
|
26
|
+
require "rake/testtask"
|
27
|
+
|
28
|
+
Rake::TestTask.new(:test) do |t|
|
29
|
+
t.libs << "test"
|
30
|
+
t.pattern = "test/**/*_test.rb"
|
31
|
+
t.verbose = false
|
32
|
+
end
|
33
|
+
|
34
|
+
task default: :test
|
data/lib/form_core.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "form_core/engine"
|
4
|
+
require "form_core/errors"
|
5
|
+
|
6
|
+
require "form_core/coder"
|
7
|
+
require "form_core/coders/hash_coder"
|
8
|
+
require "form_core/coders/yaml_coder"
|
9
|
+
|
10
|
+
require "form_core/virtual_model"
|
11
|
+
require "form_core/concerns/models/form"
|
12
|
+
require "form_core/concerns/models/field"
|
13
|
+
|
14
|
+
module FormCore
|
15
|
+
class << self
|
16
|
+
def virtual_model_class
|
17
|
+
@virtual_model_class ||= VirtualModel
|
18
|
+
end
|
19
|
+
|
20
|
+
def virtual_model_class=(klass)
|
21
|
+
unless klass && klass < VirtualModel
|
22
|
+
raise ArgumentError, "#{klass} should be sub-class of #{VirtualModel}."
|
23
|
+
end
|
24
|
+
|
25
|
+
@reserved_names = nil
|
26
|
+
@virtual_model_class = klass
|
27
|
+
end
|
28
|
+
|
29
|
+
def reserved_names
|
30
|
+
@reserved_names ||= Set.new(
|
31
|
+
%i(def class module private public protected allocate new parent superclass) +
|
32
|
+
virtual_model_class.instance_methods(true)
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
36
|
+
def virtual_model_coder_class
|
37
|
+
@virtual_model_coder_class ||= HashCoder
|
38
|
+
end
|
39
|
+
|
40
|
+
def virtual_model_coder_class=(klass)
|
41
|
+
unless klass && klass < Coder
|
42
|
+
raise ArgumentError, "#{klass} should be sub-class of #{Coder}."
|
43
|
+
end
|
44
|
+
|
45
|
+
@virtual_model_coder_class = klass
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FormCore
|
4
|
+
class Coder
|
5
|
+
cattr_accessor :strict
|
6
|
+
|
7
|
+
attr_reader :object_class
|
8
|
+
|
9
|
+
def initialize(object_class)
|
10
|
+
@object_class = object_class
|
11
|
+
end
|
12
|
+
|
13
|
+
def strict?
|
14
|
+
Coder.strict
|
15
|
+
end
|
16
|
+
|
17
|
+
def dump(_obj)
|
18
|
+
raise NotImplementedError
|
19
|
+
end
|
20
|
+
|
21
|
+
def load(_src)
|
22
|
+
raise NotImplementedError
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def new_or_raise_decoding_error
|
28
|
+
if strict?
|
29
|
+
raise DecodingDataCorrupted
|
30
|
+
else
|
31
|
+
object_class.new
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def valid_attribute_names
|
36
|
+
object_class.attribute_names + object_class._embeds_reflections.keys
|
37
|
+
end
|
38
|
+
|
39
|
+
def valid_attributes(hash)
|
40
|
+
hash.slice(*valid_attribute_names)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "yaml"
|
4
|
+
|
5
|
+
module FormCore
|
6
|
+
class HashCoder < FormCore::Coder # :nodoc:
|
7
|
+
def dump(obj)
|
8
|
+
obj&.serializable_hash || {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def load(hash)
|
12
|
+
if hash.nil? || !hash.respond_to?(:to_h)
|
13
|
+
return new_or_raise_decoding_error
|
14
|
+
end
|
15
|
+
|
16
|
+
object_class.new valid_attributes(hash)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "yaml"
|
4
|
+
|
5
|
+
module FormCore
|
6
|
+
class YAMLCoder < FormCore::Coder # :nodoc:
|
7
|
+
cattr_accessor :safe_mode
|
8
|
+
|
9
|
+
def self.whitelist_classes
|
10
|
+
@whitelist_classes ||= []
|
11
|
+
end
|
12
|
+
|
13
|
+
def safe_mode?
|
14
|
+
YAMLCoder.safe_mode
|
15
|
+
end
|
16
|
+
|
17
|
+
def dump(obj)
|
18
|
+
return YAML.dump({}) unless obj
|
19
|
+
|
20
|
+
YAML.dump obj.serializable_hash
|
21
|
+
end
|
22
|
+
|
23
|
+
def load(yaml)
|
24
|
+
return object_class.new if yaml.blank?
|
25
|
+
|
26
|
+
unless yaml.is_a?(String) && /^---/.match?(yaml)
|
27
|
+
return new_or_raise_decoding_error
|
28
|
+
end
|
29
|
+
|
30
|
+
decoded =
|
31
|
+
if safe_mode?
|
32
|
+
YAML.safe_load(yaml, YAMLCoder.whitelist_classes)
|
33
|
+
else
|
34
|
+
YAML.load(yaml)
|
35
|
+
end
|
36
|
+
unless decoded.is_a? Hash
|
37
|
+
return new_or_raise_decoding_error
|
38
|
+
end
|
39
|
+
|
40
|
+
object_class.new valid_attributes(decoded)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FormCore::Concerns
|
4
|
+
module Models
|
5
|
+
module Field
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
NAME_REGEX = /\A[a-z_][a-z_0-9]*\z/
|
9
|
+
|
10
|
+
included do
|
11
|
+
|
12
|
+
serialize :validations
|
13
|
+
serialize :options
|
14
|
+
|
15
|
+
validates :name,
|
16
|
+
presence: true,
|
17
|
+
uniqueness: {scope: :form},
|
18
|
+
exclusion: {in: FormCore.reserved_names},
|
19
|
+
format: {with: NAME_REGEX}
|
20
|
+
|
21
|
+
after_initialize do
|
22
|
+
self.validations ||= {}
|
23
|
+
self.options ||= {}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def name
|
28
|
+
self[:name]&.to_sym
|
29
|
+
end
|
30
|
+
|
31
|
+
def stored_type
|
32
|
+
raise NotImplementedError
|
33
|
+
end
|
34
|
+
|
35
|
+
def default_value
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def interpret_to(model, overrides: {})
|
40
|
+
check_model_validity!(model)
|
41
|
+
|
42
|
+
default_value = overrides.fetch(:default_value, self.default_value)
|
43
|
+
model.attribute name, stored_type, default: default_value
|
44
|
+
|
45
|
+
interpret_validations_to model, overrides
|
46
|
+
interpret_extra_to model, overrides
|
47
|
+
|
48
|
+
model
|
49
|
+
end
|
50
|
+
|
51
|
+
protected
|
52
|
+
|
53
|
+
def interpret_validations_to(model, overrides = {})
|
54
|
+
validations = overrides.fetch(:validations, (self.validations || {}))
|
55
|
+
validation_options = overrides.fetch(:validation_options) { self.options.fetch(:validation, {}) }
|
56
|
+
|
57
|
+
if validations.present?
|
58
|
+
model.validates name, **validations, **validation_options
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def interpret_extra_to(_model, _overrides = {})
|
63
|
+
end
|
64
|
+
|
65
|
+
def check_model_validity!(model)
|
66
|
+
unless model.is_a?(Class) && model < ::FormCore::VirtualModel
|
67
|
+
raise ArgumentError, "#{model} must be a #{::FormCore::VirtualModel}'s subclass"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FormCore::Concerns
|
4
|
+
module Models
|
5
|
+
module Form
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
def to_virtual_model(model_name: "Form",
|
9
|
+
fields_scope: proc { |fields| fields },
|
10
|
+
overrides: {})
|
11
|
+
model = FormCore.virtual_model_class.build model_name
|
12
|
+
|
13
|
+
append_to_virtual_model(model, fields_scope: fields_scope, overrides: overrides)
|
14
|
+
end
|
15
|
+
|
16
|
+
def append_to_virtual_model(model,
|
17
|
+
fields_scope: proc { |fields| fields },
|
18
|
+
overrides: {})
|
19
|
+
check_model_validity! model
|
20
|
+
|
21
|
+
global_overrides = overrides.fetch(:_global, {})
|
22
|
+
fields_scope.call(fields).each do |f|
|
23
|
+
f.interpret_to model, overrides: global_overrides.merge(overrides.fetch(f.name, {}))
|
24
|
+
end
|
25
|
+
|
26
|
+
model
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def check_model_validity!(model)
|
32
|
+
unless model.is_a?(Class) && model < ::FormCore::VirtualModel
|
33
|
+
raise ArgumentError, "#{model} must be a #{::FormCore::VirtualModel}'s subclass"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "duck_record"
|
4
|
+
|
5
|
+
module FormCore
|
6
|
+
class VirtualModel < ::DuckRecord::Base
|
7
|
+
# Returns the contents of the record as a nicely formatted string.
|
8
|
+
def inspect
|
9
|
+
# We check defined?(@attributes) not to issue warnings if the object is
|
10
|
+
# allocated but not initialized.
|
11
|
+
inspection =
|
12
|
+
if defined?(@attributes) && @attributes
|
13
|
+
self.class.attribute_names.collect do |name|
|
14
|
+
if has_attribute?(name)
|
15
|
+
"#{name}: #{attribute_for_inspect(name)}"
|
16
|
+
end
|
17
|
+
end.compact.join(", ")
|
18
|
+
else
|
19
|
+
"not initialized"
|
20
|
+
end
|
21
|
+
|
22
|
+
"#<VirtualModel:#{self.class.name}:#{object_id} #{inspection}>"
|
23
|
+
end
|
24
|
+
|
25
|
+
def serializable_hash(options = {})
|
26
|
+
options = (options || {}).reverse_merge include: self.class._embeds_reflections.keys
|
27
|
+
super options
|
28
|
+
end
|
29
|
+
|
30
|
+
def dump
|
31
|
+
self.class.dump(self)
|
32
|
+
end
|
33
|
+
|
34
|
+
class << self
|
35
|
+
def name
|
36
|
+
@_name ||= "Form"
|
37
|
+
end
|
38
|
+
|
39
|
+
def name=(value)
|
40
|
+
value = value.classify
|
41
|
+
raise ArgumentError, "`value` isn't a valid class name" if value.blank?
|
42
|
+
|
43
|
+
@_name = value
|
44
|
+
end
|
45
|
+
|
46
|
+
def coder
|
47
|
+
@_coder ||= FormCore.virtual_model_coder_class.new(self)
|
48
|
+
end
|
49
|
+
|
50
|
+
def coder=(klass)
|
51
|
+
unless klass && klass < Coder
|
52
|
+
raise ArgumentError, "#{klass} should be sub-class of #{Coder}."
|
53
|
+
end
|
54
|
+
|
55
|
+
@_coder = klass.new(self)
|
56
|
+
end
|
57
|
+
|
58
|
+
delegate :dump, :load, to: :coder, allow_nil: false
|
59
|
+
|
60
|
+
def build(name = nil)
|
61
|
+
klass = Class.new(self)
|
62
|
+
klass.name = name
|
63
|
+
klass
|
64
|
+
end
|
65
|
+
|
66
|
+
# Returns a string like "Post(id:integer, title:string, body:text)"
|
67
|
+
def inspect
|
68
|
+
attr_list = attribute_types.map { |name, type| "#{name}: #{type.type}" } * ", "
|
69
|
+
"#<VirtualModel:#{name}:#{object_id} #{attr_list}>"
|
70
|
+
end
|
71
|
+
|
72
|
+
def _embeds_reflections
|
73
|
+
_reflections.select { |_, v| v.is_a? DuckRecord::Reflection::EmbedsAssociationReflection }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
metadata
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: form_core_v1
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.14
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- jasl
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-02-24 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.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '5.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: duck_record
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: |
|
42
|
+
A Rails engine providing ability to generate dynamic form.
|
43
|
+
It's would make such as dynamic fields of model or questionnaire easily.
|
44
|
+
email:
|
45
|
+
- jasl9187@hotmail.com
|
46
|
+
executables: []
|
47
|
+
extensions: []
|
48
|
+
extra_rdoc_files: []
|
49
|
+
files:
|
50
|
+
- MIT-LICENSE
|
51
|
+
- README.md
|
52
|
+
- Rakefile
|
53
|
+
- lib/form_core.rb
|
54
|
+
- lib/form_core/coder.rb
|
55
|
+
- lib/form_core/coders/hash_coder.rb
|
56
|
+
- lib/form_core/coders/yaml_coder.rb
|
57
|
+
- lib/form_core/concerns/models/field.rb
|
58
|
+
- lib/form_core/concerns/models/form.rb
|
59
|
+
- lib/form_core/engine.rb
|
60
|
+
- lib/form_core/errors.rb
|
61
|
+
- lib/form_core/version.rb
|
62
|
+
- lib/form_core/virtual_model.rb
|
63
|
+
- lib/tasks/form_core_tasks.rake
|
64
|
+
homepage: https://github.com/jasl-lab/form_core
|
65
|
+
licenses:
|
66
|
+
- MIT
|
67
|
+
metadata: {}
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options: []
|
70
|
+
require_paths:
|
71
|
+
- lib
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
requirements: []
|
83
|
+
rubyforge_project:
|
84
|
+
rubygems_version: 2.6.11
|
85
|
+
signing_key:
|
86
|
+
specification_version: 4
|
87
|
+
summary: A Rails engine providing ability to generate dynamic form.
|
88
|
+
test_files: []
|