tramway-core 1.17.1.1 → 1.17.2.4
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/README.md +50 -2
- data/app/controllers/tramway/core/application_controller.rb +8 -12
- data/app/decorators/tramway/core/application_decorator.rb +16 -28
- data/app/decorators/tramway/core/associations/class_helper.rb +13 -13
- data/app/decorators/tramway/core/associations/object_helper.rb +31 -3
- data/app/decorators/tramway/core/attributes/view_helper.rb +26 -0
- data/app/decorators/tramway/core/concerns/attributes_decorator_helper.rb +47 -26
- data/app/decorators/tramway/core/delegating/class_helper.rb +9 -0
- data/app/forms/tramway/core/application_form.rb +83 -171
- data/app/forms/tramway/core/application_forms/association_object_helpers.rb +31 -0
- data/app/forms/tramway/core/application_forms/constant_class_actions.rb +7 -0
- data/app/forms/tramway/core/application_forms/constant_object_actions.rb +13 -0
- data/app/forms/tramway/core/application_forms/properties_object_helper.rb +23 -0
- data/app/forms/tramway/core/extendable_form.rb +3 -70
- data/app/forms/tramway/core/extendable_forms_helpers/class_builder.rb +34 -0
- data/app/forms/tramway/core/extendable_forms_helpers/ignored_properties_helper.rb +11 -0
- data/app/forms/tramway/core/extendable_forms_helpers/more_properties_helper.rb +27 -0
- data/app/forms/tramway/core/extendable_forms_helpers/properties_helper.rb +16 -0
- data/app/forms/tramway/core/extendable_forms_helpers/submit/class_helpers.rb +18 -0
- data/app/forms/tramway/core/extendable_forms_helpers/submit/object_helpers.rb +7 -0
- data/app/forms/tramway/core/extendable_forms_helpers/validators.rb +40 -0
- data/app/helpers/tramway/core/copy_to_clipboard_helper.rb +6 -10
- data/app/helpers/tramway/core/title_helper.rb +17 -22
- data/app/models/tramway/core/application_record.rb +38 -40
- data/app/uploaders/image_defaults.rb +2 -1
- data/app/uploaders/photo_uploader.rb +8 -8
- data/config/initializers/plurals.rb +2 -2
- data/lib/tramway/collection.rb +4 -6
- data/lib/tramway/collections.rb +4 -0
- data/lib/tramway/collections/helper.rb +15 -14
- data/lib/tramway/core.rb +22 -22
- data/lib/tramway/core/engine.rb +4 -8
- data/lib/tramway/core/generators.rb +6 -0
- data/lib/tramway/core/generators/install_generator.rb +17 -17
- data/lib/tramway/core/version.rb +1 -1
- data/lib/tramway/error.rb +12 -1
- data/lib/yaml/errors.yml +35 -0
- metadata +20 -3
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tramway::Core::ApplicationForms::AssociationObjectHelpers
|
4
|
+
def associations
|
5
|
+
@@associations
|
6
|
+
end
|
7
|
+
|
8
|
+
def define_association_method(association, class_name)
|
9
|
+
if class_name.is_a? Array
|
10
|
+
define_polymorphic_association association, class_name
|
11
|
+
else
|
12
|
+
self.class.send(:define_method, "#{association}=") do |value|
|
13
|
+
super class_name.find value
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def define_polymorphic_association(association, _class_name)
|
19
|
+
self.class.send(:define_method, "#{association}=") do |value|
|
20
|
+
association_class = value.split('_')[0..-2].join('_').camelize
|
21
|
+
association_class = association_class.constantize if association_class.is_a? String
|
22
|
+
if association_class.nil?
|
23
|
+
Tramway::Error.raise_error :tramway, :core, :application_form, :initialize, :polymorphic_class_is_nil,
|
24
|
+
association_name: association
|
25
|
+
else
|
26
|
+
super association_class.find value.split('_')[-1]
|
27
|
+
send "#{association}_type=", association_class.to_s
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tramway::Core::ApplicationForms::ConstantObjectActions
|
4
|
+
def delegating(object)
|
5
|
+
%i[to_key errors].each { |method| self.class.send(:define_method, method) { object.send method } }
|
6
|
+
end
|
7
|
+
|
8
|
+
def build_errors; end
|
9
|
+
|
10
|
+
def attributes
|
11
|
+
properties.reduce({}) { |hash, property| hash.merge! property.first => model.values[property.first.to_s] }
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tramway::Core::ApplicationForms::PropertiesObjectHelper
|
4
|
+
def form_properties(**args)
|
5
|
+
@form_properties = args
|
6
|
+
end
|
7
|
+
|
8
|
+
def form_properties_additional(**args)
|
9
|
+
@form_properties_additional = args
|
10
|
+
end
|
11
|
+
|
12
|
+
def properties
|
13
|
+
return @form_properties if @form_properties
|
14
|
+
|
15
|
+
yaml_config_file_path = Rails.root.join('app', 'forms', "#{self.class.name.underscore}.yml")
|
16
|
+
|
17
|
+
return [] unless File.exist? yaml_config_file_path
|
18
|
+
|
19
|
+
@form_properties = YAML.load_file(yaml_config_file_path).deep_symbolize_keys
|
20
|
+
@form_properties.deep_merge! @form_properties_additional if @form_properties_additional
|
21
|
+
@form_properties
|
22
|
+
end
|
23
|
+
end
|
@@ -2,80 +2,13 @@
|
|
2
2
|
|
3
3
|
class Tramway::Core::ExtendableForm
|
4
4
|
class << self
|
5
|
+
include Tramway::Core::ExtendableFormsHelpers::ClassBuilder
|
6
|
+
|
5
7
|
def new(name, simple_properties: {}, **more_properties)
|
6
8
|
if Object.const_defined? name
|
7
9
|
name.constantize
|
8
10
|
else
|
9
|
-
|
10
|
-
properties(*simple_properties.keys) if simple_properties.keys.any?
|
11
|
-
|
12
|
-
define_method 'submit' do |params|
|
13
|
-
model.values ||= {}
|
14
|
-
extended_params = params.except(*simple_properties.keys).except(*jsonb_ignored_properties(more_properties))
|
15
|
-
params.each do |key, value|
|
16
|
-
method_name = "#{key}="
|
17
|
-
send method_name, value if respond_to?(method_name)
|
18
|
-
end
|
19
|
-
model.values = extended_params.permit!.to_h.reduce(model.values) do |hash, pair|
|
20
|
-
hash.merge! pair[0] => pair[1]
|
21
|
-
end
|
22
|
-
super params
|
23
|
-
end
|
24
|
-
|
25
|
-
define_method 'properties' do
|
26
|
-
hash = simple_properties.each_with_object({}) do |property, h|
|
27
|
-
h.merge! property[0] => property[1] unless model.class.state_machines.keys.include?(property[0])
|
28
|
-
end
|
29
|
-
more_properties.reduce(hash) do |h, property|
|
30
|
-
h.merge! property[0] => {
|
31
|
-
extended_form_property: property[1][:object]
|
32
|
-
}
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
more_properties.each do |property|
|
37
|
-
define_method property[0] do
|
38
|
-
model.values[property[0]] if model.values
|
39
|
-
end
|
40
|
-
|
41
|
-
case property[1][:object].field_type
|
42
|
-
when 'file'
|
43
|
-
field = property[1][:object]
|
44
|
-
define_method "#{property[0]}=" do |value|
|
45
|
-
file_instance = property[1][:association_model].find_or_create_by "#{model.class.name.underscore}_id" => model.id, "#{field.class.name.underscore}_id" => field.id
|
46
|
-
file_instance.file = value
|
47
|
-
file_instance.save!
|
48
|
-
end
|
49
|
-
else
|
50
|
-
next unless property[1][:validates].present?
|
51
|
-
|
52
|
-
define_method "#{property[0]}=" do |value|
|
53
|
-
property[1][:validates].each do |pair|
|
54
|
-
case pair[0].to_s
|
55
|
-
when 'presence'
|
56
|
-
validator_object = "#{pair[0].to_s.camelize}Validator".constantize.new(attributes: :not_blank)
|
57
|
-
if pair[1] == 'true' && !validator_object.send(:valid?, value)
|
58
|
-
model.errors.add property[0],
|
59
|
-
I18n.t("activerecord.errors.models.#{model.class.name.underscore}.attributes.default.#{pair[0]}", value: value)
|
60
|
-
end
|
61
|
-
when 'inclusion'
|
62
|
-
in_array = pair[1][:in]
|
63
|
-
unless value.in? in_array
|
64
|
-
model.errors.add property[0],
|
65
|
-
I18n.t("activerecord.errors.models.#{model.class.name.underscore}.attributes.default.#{pair[0]}", value: value)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
define_method :jsonb_ignored_properties do |properties|
|
74
|
-
properties.map do |property|
|
75
|
-
property[0].to_s if property[1][:object].field_type == 'file'
|
76
|
-
end.compact
|
77
|
-
end
|
78
|
-
end)
|
11
|
+
build_form_class name, simple_properties, more_properties
|
79
12
|
end
|
80
13
|
end
|
81
14
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tramway::Core::ExtendableFormsHelpers::ClassBuilder
|
4
|
+
def build_form_class(name, simple_properties, more_properties)
|
5
|
+
Object.const_set(name, Class.new(::Tramway::Core::ApplicationForm) do
|
6
|
+
properties(*simple_properties.keys) if simple_properties.keys.any?
|
7
|
+
|
8
|
+
include Tramway::Core::ExtendableFormsHelpers::Submit::ObjectHelpers
|
9
|
+
include Tramway::Core::ExtendableFormsHelpers::Validators
|
10
|
+
extend Tramway::Core::ExtendableFormsHelpers::Submit::ClassHelpers
|
11
|
+
extend Tramway::Core::ExtendableFormsHelpers::PropertiesHelper
|
12
|
+
extend Tramway::Core::ExtendableFormsHelpers::MorePropertiesHelper
|
13
|
+
extend Tramway::Core::ExtendableFormsHelpers::IgnoredPropertiesHelper
|
14
|
+
|
15
|
+
define_submit_method simple_properties, more_properties
|
16
|
+
define_properties_method simple_properties, more_properties
|
17
|
+
define_ignored_properties_method
|
18
|
+
|
19
|
+
more_properties.each do |property|
|
20
|
+
define_property_method property[0]
|
21
|
+
|
22
|
+
case property[1][:object].field_type
|
23
|
+
when 'file'
|
24
|
+
field = property[1][:object]
|
25
|
+
define_file_property_assignment_method property field
|
26
|
+
else
|
27
|
+
next unless property[1][:validates].present?
|
28
|
+
|
29
|
+
define_assignment_method property
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end)
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tramway::Core::ExtendableFormsHelpers::IgnoredPropertiesHelper
|
4
|
+
def define_ignored_properties_method
|
5
|
+
define_method :jsonb_ignored_properties do |properties|
|
6
|
+
properties.map do |property|
|
7
|
+
property[0].to_s if property[1][:object].field_type == 'file'
|
8
|
+
end.compact
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tramway::Core::ExtendableFormsHelpers::MorePropertiesHelper
|
4
|
+
def define_property_method(property_name)
|
5
|
+
define_method property_name do
|
6
|
+
model.values[property_name] if model.values
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def define_assignment_method(property)
|
11
|
+
define_method "#{property[0]}=" do |value|
|
12
|
+
property[1][:validates].each do |pair|
|
13
|
+
make_validates property[0], pair, value
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def define_file_property_assignment_method(property, field)
|
19
|
+
define_method "#{property[0]}=" do |value|
|
20
|
+
file_instance = property[1][:association_model].find_or_create_by(
|
21
|
+
"#{model.class.name.underscore}_id" => model.id, "#{field.class.name.underscore}_id" => field.id
|
22
|
+
)
|
23
|
+
file_instance.file = value
|
24
|
+
file_instance.save!
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tramway::Core::ExtendableFormsHelpers::PropertiesHelper
|
4
|
+
def define_properties_method(simple_properties, more_properties)
|
5
|
+
define_method 'properties' do
|
6
|
+
hash = simple_properties.each_with_object({}) do |property, h|
|
7
|
+
h.merge! property[0] => property[1] unless model.class.state_machines.keys.include?(property[0])
|
8
|
+
end
|
9
|
+
more_properties.reduce(hash) do |h, property|
|
10
|
+
h.merge! property[0] => {
|
11
|
+
extended_form_property: property[1][:object]
|
12
|
+
}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tramway::Core::ExtendableFormsHelpers::Submit::ClassHelpers
|
4
|
+
def define_submit_method(simple_properties, more_properties)
|
5
|
+
define_method 'submit' do |params|
|
6
|
+
model.values ||= {}
|
7
|
+
extended_params = extended(simple_properties, more_properties, params)
|
8
|
+
params.each do |key, value|
|
9
|
+
method_name = "#{key}="
|
10
|
+
send method_name, value if respond_to?(method_name)
|
11
|
+
end
|
12
|
+
model.values = extended_params.reduce(model.values) do |hash, pair|
|
13
|
+
hash.merge! pair[0] => pair[1]
|
14
|
+
end
|
15
|
+
super(params) && model.errors.empty?
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tramway::Core::ExtendableFormsHelpers::Submit::ObjectHelpers
|
4
|
+
def extended(simple_properties, more_properties, params)
|
5
|
+
params.except(*simple_properties.keys).except(*jsonb_ignored_properties(more_properties)).permit!.to_h
|
6
|
+
end
|
7
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tramway::Core::ExtendableFormsHelpers::Validators
|
4
|
+
def make_validates(property_name, validation, value)
|
5
|
+
case validation[0].to_s
|
6
|
+
when 'presence'
|
7
|
+
presence_validator property_name, validation, value
|
8
|
+
when 'inclusion'
|
9
|
+
inclusion_validator property_name, validation, value
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def presence_validator(property_name, validation, value)
|
14
|
+
validator_object = PresenceValidator.new(attributes: :not_blank)
|
15
|
+
return if validation[1] == 'false'
|
16
|
+
return if validation[1] == 'true' && validator_object.send(:valid?, value)
|
17
|
+
|
18
|
+
model.errors.add(
|
19
|
+
property_name,
|
20
|
+
I18n.t(
|
21
|
+
"activerecord.errors.models.#{model.class.name.underscore}.attributes.default.#{validation[0]}",
|
22
|
+
value: value
|
23
|
+
)
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
def inclusion_validator(property_name, validation, value)
|
28
|
+
in_array = validation[1][:in]
|
29
|
+
|
30
|
+
return if value.in? in_array
|
31
|
+
|
32
|
+
model.errors.add(
|
33
|
+
property_name,
|
34
|
+
I18n.t(
|
35
|
+
"activerecord.errors.models.#{model.class.name.underscore}.attributes.default.#{validation[0]}",
|
36
|
+
value: value
|
37
|
+
)
|
38
|
+
)
|
39
|
+
end
|
40
|
+
end
|
@@ -1,15 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module Tramway
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
style: 'margin-left: 15px' do
|
10
|
-
fa_icon 'copy'
|
11
|
-
end
|
12
|
-
end
|
3
|
+
module Tramway::Core::CopyToClipboardHelper
|
4
|
+
def copy_to_clipboard(id)
|
5
|
+
button_tag class: 'btn btn-info clipboard-btn',
|
6
|
+
data: { clipboard_action: 'copy', clipboard_target: "##{id}" },
|
7
|
+
style: 'margin-left: 15px' do
|
8
|
+
fa_icon 'copy'
|
13
9
|
end
|
14
10
|
end
|
15
11
|
end
|
@@ -1,29 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module Tramway
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
raise error.message
|
13
|
-
end
|
14
|
-
end
|
3
|
+
module Tramway::Core::TitleHelper
|
4
|
+
def title(page_title = default_title)
|
5
|
+
if @application.present?
|
6
|
+
title_text = "#{page_title} | #{@application.try(:title) || @application.public_name}"
|
7
|
+
content_for(:title) { title_text }
|
8
|
+
else
|
9
|
+
Tramway::Error.raise_error(:tramway, :core, :title_helper, :title, :you_should_set_tramway_core_application)
|
10
|
+
end
|
11
|
+
end
|
15
12
|
|
16
|
-
|
17
|
-
|
18
|
-
|
13
|
+
def default_title
|
14
|
+
t('.title')
|
15
|
+
end
|
19
16
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
end
|
17
|
+
def page_title(action, model_name)
|
18
|
+
if I18n.locale == :ru
|
19
|
+
t("helpers.actions.#{action}") + ' ' + genitive(model_name)
|
20
|
+
else
|
21
|
+
t("helpers.actions.#{action}") + ' ' + model_name.model_name.human.downcase
|
27
22
|
end
|
28
23
|
end
|
29
24
|
end
|
@@ -2,52 +2,50 @@
|
|
2
2
|
|
3
3
|
require 'carrierwave/orm/activerecord' if defined?(CarrierWave::Mount)
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
audited
|
10
|
-
extend ::Enumerize
|
11
|
-
|
12
|
-
state_machine :state, initial: :active do
|
13
|
-
state :active
|
14
|
-
state :removed
|
15
|
-
|
16
|
-
event :remove do
|
17
|
-
transition active: :remove
|
18
|
-
end
|
19
|
-
end
|
5
|
+
class Tramway::Core::ApplicationRecord < ActiveRecord::Base
|
6
|
+
self.abstract_class = true
|
7
|
+
audited
|
8
|
+
extend ::Enumerize
|
20
9
|
|
21
|
-
|
22
|
-
|
23
|
-
|
10
|
+
state_machine :state, initial: :active do
|
11
|
+
state :active
|
12
|
+
state :removed
|
24
13
|
|
25
|
-
|
14
|
+
event :remove do
|
15
|
+
transition active: :remove
|
16
|
+
end
|
17
|
+
end
|
26
18
|
|
27
|
-
|
28
|
-
|
29
|
-
|
19
|
+
scope :active, -> { where state: :active }
|
20
|
+
scope :created_by_user, lambda { |user_id|
|
21
|
+
joins(:audits).where('audits.action = \'create\' AND audits.user_id = ?', user_id)
|
22
|
+
}
|
23
|
+
scope :admin_scope, ->(_arg) { all }
|
30
24
|
|
31
|
-
|
32
|
-
class << self
|
33
|
-
def human_attribute_name(attribute_name, *_args)
|
34
|
-
excepted_attributes = %w[created_at updated_at state]
|
35
|
-
if attribute_name.to_s.in? excepted_attributes
|
36
|
-
I18n.t "activerecord.attributes.tramway/core/application_record.#{attribute_name}"
|
37
|
-
else
|
38
|
-
super attribute_name
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def search_by(*attributes, **associations)
|
43
|
-
pg_search_scope :full_text_search, against: attributes, associated_against: associations
|
44
|
-
end
|
45
|
-
end
|
25
|
+
include ::PgSearch::Model
|
46
26
|
|
47
|
-
|
48
|
-
|
49
|
-
|
27
|
+
def creator
|
28
|
+
audits.where(action: :create).first.user
|
29
|
+
end
|
30
|
+
|
31
|
+
# FIXME: detect inhertited locales
|
32
|
+
class << self
|
33
|
+
def human_attribute_name(attribute_name, *_args)
|
34
|
+
excepted_attributes = %w[created_at updated_at state]
|
35
|
+
if attribute_name.to_s.in? excepted_attributes
|
36
|
+
I18n.t "activerecord.attributes.tramway/core/application_record.#{attribute_name}"
|
37
|
+
else
|
38
|
+
super attribute_name
|
50
39
|
end
|
51
40
|
end
|
41
|
+
|
42
|
+
def search_by(*attributes, **associations)
|
43
|
+
pg_search_scope :full_text_search, against: attributes, associated_against: associations
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# FIXME: detect inhertited locales
|
48
|
+
def human_state_name
|
49
|
+
I18n.t "activerecord.state_machines.tramway/core/application_record.state.states.#{state}"
|
52
50
|
end
|
53
51
|
end
|