script_core 0.0.4 → 0.0.5
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.
- checksums.yaml +4 -4
- data/.gitattributes +1 -1
- data/.gitignore +15 -1
- data/.rubocop.yml +10 -2
- data/.ruby-version +1 -1
- data/.travis.yml +6 -0
- data/Gemfile +32 -0
- data/README.md +169 -6
- data/Rakefile +11 -0
- data/Vagrantfile +1 -1
- data/bin/rails +25 -0
- data/bootstrap.sh +2 -3
- data/dev.yml +4 -4
- data/ext/enterprise_script_service/Rakefile +5 -4
- data/ext/enterprise_script_service/mruby_config.rb +1 -0
- data/lib/script_core.rb +17 -15
- data/lib/script_core/engine.rb +1 -0
- data/lib/script_core/executable.rb +1 -1
- data/lib/script_core/railtie.rb +8 -0
- data/lib/script_core/spawner.rb +1 -0
- data/lib/script_core/version.rb +1 -1
- data/lib/tasks/mruby/engine.gembox.example +19 -0
- data/lib/tasks/mruby/lib/.keep +0 -0
- data/lib/tasks/script_core.rake +111 -0
- data/script/regression +7 -5
- data/script_core.gemspec +2 -2
- data/spec/dummy/Rakefile +8 -0
- data/spec/dummy/app/assets/config/manifest.js +3 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/javascripts/application.es6 +56 -0
- data/spec/dummy/app/assets/stylesheets/application.scss +65 -0
- data/spec/dummy/app/controllers/application_controller.rb +4 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/controllers/fields/application_controller.rb +25 -0
- data/spec/dummy/app/controllers/fields/options_controller.rb +26 -0
- data/spec/dummy/app/controllers/fields/validations_controller.rb +26 -0
- data/spec/dummy/app/controllers/forms/application_controller.rb +14 -0
- data/spec/dummy/app/controllers/forms/fields_controller.rb +56 -0
- data/spec/dummy/app/controllers/forms/formulas/application_controller.rb +19 -0
- data/spec/dummy/app/controllers/forms/formulas/playgrounds_controller.rb +29 -0
- data/spec/dummy/app/controllers/forms/formulas_controller.rb +56 -0
- data/spec/dummy/app/controllers/forms_controller.rb +58 -0
- data/spec/dummy/app/controllers/home_controller.rb +7 -0
- data/spec/dummy/app/controllers/nested_forms/application_controller.rb +12 -0
- data/spec/dummy/app/controllers/nested_forms/fields_controller.rb +50 -0
- data/spec/dummy/app/controllers/playgrounds_controller.rb +29 -0
- data/spec/dummy/app/decorators/.keep +0 -0
- data/spec/dummy/app/helpers/application_helper.rb +21 -0
- data/spec/dummy/app/helpers/fields_helper.rb +32 -0
- data/spec/dummy/app/helpers/forms_helper.rb +14 -0
- data/spec/dummy/app/jobs/application_job.rb +4 -0
- data/spec/dummy/app/lib/script_engine.rb +22 -0
- data/spec/dummy/app/models/application_record.rb +8 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/models/concerns/acts_as_default_value.rb +152 -0
- data/spec/dummy/app/models/concerns/enum_attribute_localizable.rb +32 -0
- data/spec/dummy/app/models/concerns/fields/validations/acceptance.rb +18 -0
- data/spec/dummy/app/models/concerns/fields/validations/confirmation.rb +18 -0
- data/spec/dummy/app/models/concerns/fields/validations/exclusion.rb +35 -0
- data/spec/dummy/app/models/concerns/fields/validations/format.rb +45 -0
- data/spec/dummy/app/models/concerns/fields/validations/inclusion.rb +35 -0
- data/spec/dummy/app/models/concerns/fields/validations/length.rb +59 -0
- data/spec/dummy/app/models/concerns/fields/validations/numericality.rb +56 -0
- data/spec/dummy/app/models/concerns/fields/validations/presence.rb +18 -0
- data/spec/dummy/app/models/concerns/form_core/acts_as_default_value.rb +143 -0
- data/spec/dummy/app/models/field.rb +67 -0
- data/spec/dummy/app/models/field_options.rb +90 -0
- data/spec/dummy/app/models/fields.rb +10 -0
- data/spec/dummy/app/models/fields/boolean_field.rb +12 -0
- data/spec/dummy/app/models/fields/decimal_field.rb +12 -0
- data/spec/dummy/app/models/fields/integer_field.rb +20 -0
- data/spec/dummy/app/models/fields/multiple_nested_form_field.rb +35 -0
- data/spec/dummy/app/models/fields/nested_form_field.rb +37 -0
- data/spec/dummy/app/models/fields/options/boolean_field.rb +6 -0
- data/spec/dummy/app/models/fields/options/decimal_field.rb +12 -0
- data/spec/dummy/app/models/fields/options/integer_field.rb +13 -0
- data/spec/dummy/app/models/fields/options/multiple_nested_form_field.rb +6 -0
- data/spec/dummy/app/models/fields/options/nested_form_field.rb +6 -0
- data/spec/dummy/app/models/fields/options/text_field.rb +7 -0
- data/spec/dummy/app/models/fields/text_field.rb +12 -0
- data/spec/dummy/app/models/fields/validations/boolean_field.rb +7 -0
- data/spec/dummy/app/models/fields/validations/decimal_field.rb +8 -0
- data/spec/dummy/app/models/fields/validations/integer_field.rb +8 -0
- data/spec/dummy/app/models/fields/validations/multiple_nested_form_field.rb +8 -0
- data/spec/dummy/app/models/fields/validations/nested_form_field.rb +7 -0
- data/spec/dummy/app/models/fields/validations/text_field.rb +9 -0
- data/spec/dummy/app/models/form.rb +8 -0
- data/spec/dummy/app/models/formula.rb +8 -0
- data/spec/dummy/app/models/metal_form.rb +9 -0
- data/spec/dummy/app/models/nested_form.rb +5 -0
- data/spec/dummy/app/models/virtual_model.rb +23 -0
- data/spec/dummy/app/presenters/application_presenter.rb +11 -0
- data/spec/dummy/app/presenters/concerns/fields/presenter_for_number_field.rb +36 -0
- data/spec/dummy/app/presenters/fields/boolean_field_presenter.rb +13 -0
- data/spec/dummy/app/presenters/fields/composite_field_presenter.rb +13 -0
- data/spec/dummy/app/presenters/fields/decimal_field_presenter.rb +7 -0
- data/spec/dummy/app/presenters/fields/field_presenter.rb +44 -0
- data/spec/dummy/app/presenters/fields/integer_field_presenter.rb +11 -0
- data/spec/dummy/app/presenters/fields/multiple_nested_form_field_presenter.rb +9 -0
- data/spec/dummy/app/presenters/fields/nested_form_field_presenter.rb +9 -0
- data/spec/dummy/app/presenters/fields/text_field_presenter.rb +10 -0
- data/spec/dummy/app/views/_form_core/field_options/_decimal_field.html.erb +9 -0
- data/spec/dummy/app/views/_form_core/field_options/_integer_field.html.erb +10 -0
- data/spec/dummy/app/views/_form_core/field_options/_text_field.html.erb +12 -0
- data/spec/dummy/app/views/_form_core/fields/_boolean_field.html.erb +11 -0
- data/spec/dummy/app/views/_form_core/fields/_decimal_field.html.erb +9 -0
- data/spec/dummy/app/views/_form_core/fields/_integer_field.html.erb +9 -0
- data/spec/dummy/app/views/_form_core/fields/_multiple_nested_form_field.html.erb +23 -0
- data/spec/dummy/app/views/_form_core/fields/_nested_form.html.erb +37 -0
- data/spec/dummy/app/views/_form_core/fields/_nested_form_field.html.erb +42 -0
- data/spec/dummy/app/views/_form_core/fields/_text_field.html.erb +13 -0
- data/spec/dummy/app/views/_form_core/preview/_form.html.erb +17 -0
- data/spec/dummy/app/views/_form_core/preview/_nested_form.html.erb +22 -0
- data/spec/dummy/app/views/_form_core/render/_form.html.erb +39 -0
- data/spec/dummy/app/views/_form_core/validations/_acceptance.html.erb +12 -0
- data/spec/dummy/app/views/_form_core/validations/_confirmation.html.erb +12 -0
- data/spec/dummy/app/views/_form_core/validations/_exclusion.html.erb +2 -0
- data/spec/dummy/app/views/_form_core/validations/_format.html.erb +37 -0
- data/spec/dummy/app/views/_form_core/validations/_inclusion.html.erb +2 -0
- data/spec/dummy/app/views/_form_core/validations/_length.html.erb +44 -0
- data/spec/dummy/app/views/_form_core/validations/_numericality.html.erb +45 -0
- data/spec/dummy/app/views/_form_core/validations/_presence.html.erb +12 -0
- data/spec/dummy/app/views/fields/options/_form.html.erb +29 -0
- data/spec/dummy/app/views/fields/options/edit.html.erb +6 -0
- data/spec/dummy/app/views/fields/validations/_form.html.erb +34 -0
- data/spec/dummy/app/views/fields/validations/edit.html.erb +6 -0
- data/spec/dummy/app/views/forms/_form.html.erb +41 -0
- data/spec/dummy/app/views/forms/edit.html.erb +6 -0
- data/spec/dummy/app/views/forms/fields/_form.html.erb +71 -0
- data/spec/dummy/app/views/forms/fields/edit.html.erb +6 -0
- data/spec/dummy/app/views/forms/fields/index.html.erb +42 -0
- data/spec/dummy/app/views/forms/fields/new.html.erb +6 -0
- data/spec/dummy/app/views/forms/formulas/_form.html.erb +41 -0
- data/spec/dummy/app/views/forms/formulas/edit.html.erb +6 -0
- data/spec/dummy/app/views/forms/formulas/index.html.erb +28 -0
- data/spec/dummy/app/views/forms/formulas/new.html.erb +6 -0
- data/spec/dummy/app/views/forms/formulas/playgrounds/create.html.erb +48 -0
- data/spec/dummy/app/views/forms/formulas/playgrounds/show.html.erb +14 -0
- data/spec/dummy/app/views/forms/index.html.erb +31 -0
- data/spec/dummy/app/views/forms/new.html.erb +6 -0
- data/spec/dummy/app/views/home/index.html.erb +5 -0
- data/spec/dummy/app/views/layouts/_alert.html.erb +4 -0
- data/spec/dummy/app/views/layouts/_footer.html.erb +13 -0
- data/spec/dummy/app/views/layouts/_nav.html.erb +11 -0
- data/spec/dummy/app/views/layouts/_notice.html.erb +4 -0
- data/spec/dummy/app/views/layouts/application.html.erb +25 -0
- data/spec/dummy/app/views/layouts/forms.html.erb +33 -0
- data/spec/dummy/app/views/nested_forms/fields/_form.html.erb +68 -0
- data/spec/dummy/app/views/nested_forms/fields/edit.html.erb +6 -0
- data/spec/dummy/app/views/nested_forms/fields/index.html.erb +39 -0
- data/spec/dummy/app/views/nested_forms/fields/new.html.erb +6 -0
- data/spec/dummy/app/views/playgrounds/_form.html.erb +13 -0
- data/spec/dummy/app/views/playgrounds/create.html.erb +51 -0
- data/spec/dummy/app/views/playgrounds/show.html.erb +7 -0
- data/spec/dummy/bin/bundle +5 -0
- data/spec/dummy/bin/rails +6 -0
- data/spec/dummy/bin/rake +6 -0
- data/spec/dummy/bin/setup +40 -0
- data/spec/dummy/bin/update +35 -0
- data/spec/dummy/bin/yarn +13 -0
- data/spec/dummy/config.ru +7 -0
- data/spec/dummy/config/application.rb +35 -0
- data/spec/dummy/config/boot.rb +7 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +7 -0
- data/spec/dummy/config/environments/development.rb +58 -0
- data/spec/dummy/config/environments/production.rb +85 -0
- data/spec/dummy/config/environments/test.rb +41 -0
- data/spec/dummy/config/initializers/application_controller_renderer.rb +10 -0
- data/spec/dummy/config/initializers/assets.rb +16 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +9 -0
- data/spec/dummy/config/initializers/content_security_policy.rb +27 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +7 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +6 -0
- data/spec/dummy/config/initializers/form_core.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +18 -0
- data/spec/dummy/config/initializers/mime_types.rb +6 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +16 -0
- data/spec/dummy/config/locales/en.yml +33 -0
- data/spec/dummy/config/puma.rb +36 -0
- data/spec/dummy/config/routes.rb +31 -0
- data/spec/dummy/config/spring.rb +8 -0
- data/spec/dummy/config/storage.yml +34 -0
- data/spec/dummy/db/migrate/20180916202025_create_forms.form_core.rb +12 -0
- data/spec/dummy/db/migrate/20180916202026_add_columns_to_forms.rb +10 -0
- data/spec/dummy/db/migrate/20180916202027_add_attachable_to_forms.rb +9 -0
- data/spec/dummy/db/migrate/20180916202030_create_fields.form_core.rb +17 -0
- data/spec/dummy/db/migrate/20180916202121_add_columns_to_fields.rb +10 -0
- data/spec/dummy/db/migrate/20180916202124_add_position_to_fields.rb +9 -0
- data/spec/dummy/db/migrate/20181111111412_create_formulas.rb +13 -0
- data/spec/dummy/db/schema.rb +52 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/lib/monkey_patches/active_support.rb +3 -0
- data/spec/dummy/lib/monkey_patches/active_support/concern+prependable.rb +28 -0
- data/spec/dummy/lib/monkey_patches/big_decimal.rb +8 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/mruby/engine.gembox +19 -0
- data/spec/dummy/mruby/lib/.keep +0 -0
- data/spec/dummy/mruby/lib/core_ext.rb +62 -0
- data/spec/dummy/mruby/lib/harden.rb +1 -0
- data/spec/dummy/mruby/lib/input.rb +20 -0
- data/spec/dummy/mruby/lib/io.rb +19 -0
- data/spec/dummy/mruby/lib/output.rb +35 -0
- data/spec/dummy/mruby/lib/script_kernel.rb +12 -0
- data/spec/dummy/package.json +5 -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/apple-touch-icon-precomposed.png +0 -0
- data/spec/dummy/public/apple-touch-icon.png +0 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/storage/.keep +0 -0
- data/spec/dummy/test/controllers/.keep +0 -0
- data/spec/dummy/test/fixtures/.keep +0 -0
- data/spec/dummy/test/models/.keep +0 -0
- data/spec/script_core_spec.rb +2 -2
- data/spec/spec_helper.rb +2 -2
- metadata +199 -5
- data/circle.yml +0 -9
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Concerns::Fields
|
|
4
|
+
module Validations::Numericality
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
included do
|
|
8
|
+
embeds_one :numericality, class_name: "Concerns::Fields::Validations::Numericality::NumericalityOptions"
|
|
9
|
+
accepts_nested_attributes_for :numericality
|
|
10
|
+
|
|
11
|
+
after_initialize do
|
|
12
|
+
build_numericality unless numericality
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def interpret_to(model, field_name, accessibility, options = {})
|
|
17
|
+
super
|
|
18
|
+
numericality&.interpret_to model, field_name, accessibility, options
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class NumericalityOptions < FieldOptions
|
|
22
|
+
attribute :lower_bound_check, :string, default: "disabled"
|
|
23
|
+
attribute :upper_bound_check, :string, default: "disabled"
|
|
24
|
+
|
|
25
|
+
attribute :lower_bound_value, :float, default: 0.0
|
|
26
|
+
attribute :upper_bound_value, :float, default: 0.0
|
|
27
|
+
|
|
28
|
+
enum lower_bound_check: {
|
|
29
|
+
disabled: "disabled",
|
|
30
|
+
greater_than: "greater_than",
|
|
31
|
+
greater_than_or_equal_to: "greater_than_or_equal_to"
|
|
32
|
+
}, _prefix: :lower_bound_check
|
|
33
|
+
enum upper_bound_check: {
|
|
34
|
+
disabled: "disabled",
|
|
35
|
+
less_than: "less_than",
|
|
36
|
+
less_than_or_equal_to: "less_than_or_equal_to"
|
|
37
|
+
}, _prefix: :upper_bound_check
|
|
38
|
+
|
|
39
|
+
validates :upper_bound_value,
|
|
40
|
+
numericality: {
|
|
41
|
+
greater_than: :lower_bound_value
|
|
42
|
+
},
|
|
43
|
+
if: proc { upper_bound_check != "disabled" && lower_bound_check != "disabled" }
|
|
44
|
+
|
|
45
|
+
def interpret_to(model, field_name, _accessibility, _options = {})
|
|
46
|
+
options = {}
|
|
47
|
+
options[lower_bound_check] = lower_bound_value unless lower_bound_check_disabled?
|
|
48
|
+
options[upper_bound_check] = upper_bound_value unless upper_bound_check_disabled?
|
|
49
|
+
return if options.empty?
|
|
50
|
+
|
|
51
|
+
options.symbolize_keys!
|
|
52
|
+
model.validates field_name, numericality: options, allow_blank: true
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Concerns::Fields
|
|
4
|
+
module Validations::Presence
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
included do
|
|
8
|
+
attribute :presence, :boolean, default: false
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def interpret_to(model, field_name, _accessibility, _options = {})
|
|
12
|
+
super
|
|
13
|
+
return unless presence
|
|
14
|
+
|
|
15
|
+
model.validates field_name, presence: true
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# https://github.com/FooBarWidget/default_value_for
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) 2008-2012 Phusion
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in
|
|
15
|
+
# all copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
23
|
+
# THE SOFTWARE.
|
|
24
|
+
|
|
25
|
+
module FormCore
|
|
26
|
+
module ActsAsDefaultValue
|
|
27
|
+
extend ActiveSupport::Concern
|
|
28
|
+
|
|
29
|
+
class NormalValueContainer
|
|
30
|
+
def initialize(value)
|
|
31
|
+
@value = value
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def evaluate(_instance)
|
|
35
|
+
if @value.duplicable?
|
|
36
|
+
@value.dup
|
|
37
|
+
else
|
|
38
|
+
@value
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
class BlockValueContainer
|
|
44
|
+
def initialize(block)
|
|
45
|
+
@block = block
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def evaluate(instance)
|
|
49
|
+
if @block.arity == 0
|
|
50
|
+
@block.call
|
|
51
|
+
else
|
|
52
|
+
@block.call(instance)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
included do
|
|
58
|
+
after_initialize :set_default_values
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def initialize(attributes = nil)
|
|
62
|
+
@initialization_attributes = attributes.is_a?(Hash) ? attributes.stringify_keys : {}
|
|
63
|
+
super
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def set_default_values
|
|
67
|
+
self.class._all_default_attribute_values.each do |attribute, container|
|
|
68
|
+
next unless new_record? || self.class._all_default_attribute_values_not_allowing_nil.include?(attribute)
|
|
69
|
+
|
|
70
|
+
attribute_blank =
|
|
71
|
+
if self.class.attribute_types[attribute]&.type == :boolean
|
|
72
|
+
send(attribute).nil?
|
|
73
|
+
else
|
|
74
|
+
send(attribute).blank?
|
|
75
|
+
end
|
|
76
|
+
next unless attribute_blank
|
|
77
|
+
|
|
78
|
+
# allow explicitly setting nil through allow nil option
|
|
79
|
+
next if @initialization_attributes.is_a?(Hash) &&
|
|
80
|
+
(
|
|
81
|
+
@initialization_attributes.key?(attribute) ||
|
|
82
|
+
(
|
|
83
|
+
@initialization_attributes.key?("#{attribute}_attributes") &&
|
|
84
|
+
nested_attributes_options.stringify_keys[attribute]
|
|
85
|
+
)
|
|
86
|
+
) &&
|
|
87
|
+
!self.class._all_default_attribute_values_not_allowing_nil.include?(attribute)
|
|
88
|
+
|
|
89
|
+
send("#{attribute}=", container.evaluate(self))
|
|
90
|
+
|
|
91
|
+
clear_attribute_changes [attribute] if has_attribute?(attribute)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
module ClassMethods
|
|
96
|
+
def _default_attribute_values # :nodoc:
|
|
97
|
+
@default_attribute_values ||= {}
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def _default_attribute_values_not_allowing_nil # :nodoc:
|
|
101
|
+
@default_attribute_values_not_allowing_nil ||= Set.new
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def _all_default_attribute_values # :nodoc:
|
|
105
|
+
if superclass.respond_to?(:_default_attribute_values)
|
|
106
|
+
superclass._all_default_attribute_values.merge(_default_attribute_values)
|
|
107
|
+
else
|
|
108
|
+
_default_attribute_values
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def _all_default_attribute_values_not_allowing_nil # :nodoc:
|
|
113
|
+
if superclass.respond_to?(:_default_attribute_values_not_allowing_nil)
|
|
114
|
+
superclass._all_default_attribute_values_not_allowing_nil + _default_attribute_values_not_allowing_nil
|
|
115
|
+
else
|
|
116
|
+
_default_attribute_values_not_allowing_nil
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Declares a default value for the given attribute.
|
|
121
|
+
#
|
|
122
|
+
# Sets the default value to the given options parameter
|
|
123
|
+
#
|
|
124
|
+
# The <tt>options</tt> can be used to specify the following things:
|
|
125
|
+
# * <tt>allow_nil (default: true)</tt> - Sets explicitly passed nil values if option is set to true.
|
|
126
|
+
def default_value_for(attribute, value, **options)
|
|
127
|
+
allow_nil = options.fetch(:allow_nil, true)
|
|
128
|
+
|
|
129
|
+
container =
|
|
130
|
+
if value.is_a? Proc
|
|
131
|
+
BlockValueContainer.new(value)
|
|
132
|
+
else
|
|
133
|
+
NormalValueContainer.new(value)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
_default_attribute_values[attribute.to_s] = container
|
|
137
|
+
_default_attribute_values_not_allowing_nil << attribute.to_s unless allow_nil
|
|
138
|
+
|
|
139
|
+
attribute
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Field < ApplicationRecord
|
|
4
|
+
include FormCore::Concerns::Models::Field
|
|
5
|
+
|
|
6
|
+
self.table_name = "fields"
|
|
7
|
+
|
|
8
|
+
belongs_to :form, class_name: "MetalForm", foreign_key: "form_id", touch: true
|
|
9
|
+
|
|
10
|
+
validates :label,
|
|
11
|
+
presence: true
|
|
12
|
+
validates :type,
|
|
13
|
+
inclusion: {
|
|
14
|
+
in: ->(_) { Field.descendants.map(&:to_s) }
|
|
15
|
+
},
|
|
16
|
+
allow_blank: false
|
|
17
|
+
|
|
18
|
+
default_value_for :name,
|
|
19
|
+
->(_) { "field_#{SecureRandom.hex(3)}" },
|
|
20
|
+
allow_nil: false
|
|
21
|
+
|
|
22
|
+
def self.type_key
|
|
23
|
+
model_name.name.split("::").last.underscore
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def type_key
|
|
27
|
+
self.class.type_key
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def options_configurable?
|
|
31
|
+
options.is_a?(FieldOptions) && options.attributes.any?
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def validations_configurable?
|
|
35
|
+
validations.is_a?(FieldOptions) && validations.attributes.any?
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
protected
|
|
39
|
+
|
|
40
|
+
def interpret_validations_to(model, accessibility, overrides = {})
|
|
41
|
+
return unless accessibility == :read_and_write
|
|
42
|
+
|
|
43
|
+
validations_overrides = overrides.fetch(:validations) { {} }
|
|
44
|
+
validations =
|
|
45
|
+
if validations_overrides.any?
|
|
46
|
+
self.validations.dup.update(validations_overrides)
|
|
47
|
+
else
|
|
48
|
+
self.validations
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
validations.interpret_to(model, name, accessibility)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def interpret_extra_to(model, accessibility, overrides = {})
|
|
55
|
+
options_overrides = overrides.fetch(:options) { {} }
|
|
56
|
+
options =
|
|
57
|
+
if options_overrides.any?
|
|
58
|
+
self.options.dup.update(options_overrides)
|
|
59
|
+
else
|
|
60
|
+
self.options
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
options.interpret_to(model, name, accessibility)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
require_dependency "fields"
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class FieldOptions < DuckRecord::Base
|
|
4
|
+
include FormCore::ActsAsDefaultValue
|
|
5
|
+
include EnumAttributeLocalizable
|
|
6
|
+
|
|
7
|
+
class_attribute :keeping_old_serialization
|
|
8
|
+
|
|
9
|
+
attr_accessor :raw_attributes
|
|
10
|
+
|
|
11
|
+
def interpret_to(_model, _field_name, _accessibility, _options = {}); end
|
|
12
|
+
|
|
13
|
+
def serializable_hash(options = {})
|
|
14
|
+
options = (options || {}).reverse_merge include: self.class._embeds_reflections.keys
|
|
15
|
+
super options
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def _assign_attribute(k, v)
|
|
21
|
+
return unless respond_to?("#{k}=")
|
|
22
|
+
|
|
23
|
+
public_send("#{k}=", v)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
class << self
|
|
27
|
+
def _embeds_reflections
|
|
28
|
+
_reflections.select { |_, v| v.is_a? DuckRecord::Reflection::EmbedsAssociationReflection }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def model_version
|
|
32
|
+
1
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def root_key_for_serialization
|
|
36
|
+
"#{self}.#{model_version}"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def dump(obj)
|
|
40
|
+
return YAML.dump({}) unless obj
|
|
41
|
+
|
|
42
|
+
serializable_hash =
|
|
43
|
+
if obj.respond_to?(:serializable_hash)
|
|
44
|
+
obj.serializable_hash
|
|
45
|
+
elsif obj.respond_to?(:to_hash)
|
|
46
|
+
obj.to_hash
|
|
47
|
+
else
|
|
48
|
+
raise ArgumentError, "`obj` required can be cast to `Hash` -- #{obj.class}"
|
|
49
|
+
end.stringify_keys
|
|
50
|
+
|
|
51
|
+
data = {root_key_for_serialization => serializable_hash}
|
|
52
|
+
data.reverse_merge! obj.raw_attributes if keeping_old_serialization
|
|
53
|
+
|
|
54
|
+
YAML.dump(data)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def load(yaml_or_hash)
|
|
58
|
+
case yaml_or_hash
|
|
59
|
+
when Hash
|
|
60
|
+
load_from_hash(yaml_or_hash)
|
|
61
|
+
when String
|
|
62
|
+
load_from_yaml(yaml_or_hash)
|
|
63
|
+
else
|
|
64
|
+
new
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
WHITELIST_CLASSES = [BigDecimal, Date, Time, Symbol].freeze
|
|
69
|
+
def load_from_yaml(yaml)
|
|
70
|
+
return new if yaml.blank?
|
|
71
|
+
|
|
72
|
+
return new unless yaml.is_a?(String) && /^---/.match?(yaml)
|
|
73
|
+
|
|
74
|
+
decoded = YAML.safe_load(yaml, WHITELIST_CLASSES)
|
|
75
|
+
return new unless decoded.is_a? Hash
|
|
76
|
+
|
|
77
|
+
record = new decoded[root_key_for_serialization]
|
|
78
|
+
record.raw_attributes = decoded.freeze
|
|
79
|
+
record
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def load_from_hash(hash)
|
|
83
|
+
return new if hash.blank?
|
|
84
|
+
|
|
85
|
+
record = new hash[root_key_for_serialization]
|
|
86
|
+
record.raw_attributes = hash.freeze
|
|
87
|
+
record
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Fields
|
|
4
|
+
class IntegerField < Field
|
|
5
|
+
serialize :validations, Validations::IntegerField
|
|
6
|
+
serialize :options, Options::IntegerField
|
|
7
|
+
|
|
8
|
+
def stored_type
|
|
9
|
+
:integer
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
protected
|
|
13
|
+
|
|
14
|
+
def interpret_extra_to(model, accessibility, _overrides = {})
|
|
15
|
+
return if accessibility != :read_and_write
|
|
16
|
+
|
|
17
|
+
model.validates name, numericality: {only_integer: true}, allow_blank: true
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Fields
|
|
4
|
+
class MultipleNestedFormField < Field
|
|
5
|
+
has_one :nested_form, as: :attachable, dependent: :destroy
|
|
6
|
+
|
|
7
|
+
after_create do
|
|
8
|
+
build_nested_form.save!
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
serialize :validations, Validations::MultipleNestedFormField
|
|
12
|
+
serialize :options, Options::MultipleNestedFormField
|
|
13
|
+
|
|
14
|
+
def interpret_to(model, overrides: {})
|
|
15
|
+
check_model_validity!(model)
|
|
16
|
+
|
|
17
|
+
accessibility = overrides.fetch(:accessibility, self.accessibility)
|
|
18
|
+
return model if accessibility == :hidden
|
|
19
|
+
|
|
20
|
+
overrides[:name] = name
|
|
21
|
+
|
|
22
|
+
nested_model = nested_form.to_virtual_model(overrides: {_global: {accessibility: accessibility}})
|
|
23
|
+
|
|
24
|
+
model.nested_models[name] = nested_model
|
|
25
|
+
|
|
26
|
+
model.embeds_many name, anonymous_class: nested_model, validate: true
|
|
27
|
+
model.accepts_nested_attributes_for name, reject_if: :all_blank
|
|
28
|
+
|
|
29
|
+
interpret_validations_to model, accessibility, overrides
|
|
30
|
+
interpret_extra_to model, accessibility, overrides
|
|
31
|
+
|
|
32
|
+
model
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|