eac_rails_utils 0.24.0 → 0.26.0

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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/app/helpers/eac_rails_utils/data_table_helper/data_table.rb +10 -5
  3. data/app/helpers/eac_rails_utils/links_helper/object_link.rb +78 -0
  4. data/app/helpers/eac_rails_utils/links_helper/object_path.rb +39 -0
  5. data/app/helpers/eac_rails_utils/links_helper.rb +35 -51
  6. data/app/helpers/eac_rails_utils/menus_helper/bootstrap_gui_builder.rb +1 -1
  7. data/lib/eac_rails_utils/engine.rb +4 -1
  8. data/lib/eac_rails_utils/engine_helper.rb +1 -5
  9. data/lib/eac_rails_utils/menus/action.rb +0 -3
  10. data/lib/eac_rails_utils/menus/group.rb +0 -4
  11. data/lib/eac_rails_utils/menus/node.rb +0 -2
  12. data/lib/eac_rails_utils/menus.rb +0 -2
  13. data/lib/eac_rails_utils/models/tableless/attributes.rb +0 -2
  14. data/lib/eac_rails_utils/models/tableless/columns.rb +0 -2
  15. data/lib/eac_rails_utils/models/tableless/strict_loading.rb +1 -5
  16. data/lib/eac_rails_utils/models/tableless.rb +0 -3
  17. data/lib/eac_rails_utils/models/tableless_associations/has_many_for_active_model.rb +32 -0
  18. data/lib/eac_rails_utils/models/tableless_associations/has_many_for_active_model_association.rb +78 -0
  19. data/lib/eac_rails_utils/models/tableless_associations/hooks.rb +0 -1
  20. data/lib/eac_rails_utils/models/tableless_associations/override_methods.rb +3 -1
  21. data/lib/eac_rails_utils/models/tableless_associations.rb +2 -8
  22. data/lib/eac_rails_utils/models/validations.rb +0 -2
  23. data/lib/eac_rails_utils/models.rb +0 -2
  24. data/lib/eac_rails_utils/patches/active_model.rb +0 -1
  25. data/lib/eac_rails_utils/patches/active_model_associations.rb +0 -3
  26. data/lib/eac_rails_utils/patches/application.rb +0 -2
  27. data/lib/eac_rails_utils/patches/numeric/number_helper.rb +2 -4
  28. data/lib/eac_rails_utils/patches/numeric.rb +0 -1
  29. data/lib/eac_rails_utils/patches/rails_5_2/active_model_association_method_fix.rb +0 -3
  30. data/lib/eac_rails_utils/patches/rails_5_2.rb +0 -3
  31. data/lib/eac_rails_utils/patches.rb +0 -2
  32. data/lib/eac_rails_utils/rspec/setup/models_utils.rb +1 -3
  33. data/lib/eac_rails_utils/rspec/setup.rb +0 -2
  34. data/lib/eac_rails_utils/rspec.rb +0 -1
  35. data/lib/eac_rails_utils/version.rb +1 -1
  36. data/lib/eac_rails_utils.rb +8 -2
  37. metadata +10 -15
  38. data/lib/active_record/associations/builder/has_many_for_active_model.rb +0 -24
  39. data/lib/active_record/associations/has_many_for_active_model_association.rb +0 -72
  40. data/lib/activemodel/associations.rb +0 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 10597063c9780ca174f0236d4bb7a87af4b5702d0617b84406ebf613afe7a822
4
- data.tar.gz: befada54dbc901d1d2e43d33606f1a3219fd288cf3a8d52178495e337fe4d8de
3
+ metadata.gz: e9c8f1cb71b2ab76e3667ef5b6adae75ee9e663efdb4fdbeb20d9ff6a42ec093
4
+ data.tar.gz: e663317c490abc9a86156fcd19c9acc1a6d4165c0828f1c08ea518d0716173da
5
5
  SHA512:
6
- metadata.gz: 205e2134c2f1d5b5770dff69c1ec55b87fc454a563dc0e1c01623341d9b2d6701b81f502a01efcf3772bccbef45a6405ea4040bf295d2f851874fa094a2069fe
7
- data.tar.gz: d90285c437b1ad93874601d4077e1c1d86c3df012348860523a8bb70ae33c395fbc0cb23b0089cef75e3bc4255d59c8d3329bec4ca4004266bcae513fd12c676
6
+ metadata.gz: c7d5206c741289efe2f96e5043fbbbd7cc2219a47184f078b934aed6176fcab54db7cdb61ef2279a1eb7e2828a6155538bc9289e4279a1158d45723e14491ec9
7
+ data.tar.gz: 9b3d804b520518ab96f40c25bb9518e09f6b23c9d8b8ca05bf8a6f24a8de4c17a42a9364eb6f9766393eb81a07ec35e15f5ec17b53a6e8235d25cf104c7ed7c9
@@ -5,11 +5,16 @@ require 'eac_ruby_utils/core_ext'
5
5
  module EacRailsUtils
6
6
  module DataTableHelper
7
7
  class DataTable
8
+ CONTAINER_CSS_CLASS = %w[table-responsive].freeze
9
+ TABLE_CSS_CLASSES = %w[table table-striped].freeze
10
+
8
11
  common_constructor :view, :dataset, :setup_block, block_arg: true
9
12
 
10
13
  def output
11
- view.content_tag(:table, id: id) do
12
- head << body
14
+ view.content_tag(:div, class: CONTAINER_CSS_CLASS) do
15
+ view.content_tag(:table, id: id, class: TABLE_CSS_CLASSES) do
16
+ head << body
17
+ end
13
18
  end << script
14
19
  end
15
20
 
@@ -40,9 +45,9 @@ module EacRailsUtils
40
45
  def script
41
46
  view.javascript_tag <<~JS_CODE
42
47
  $(document).ready(function () {
43
- $('##{id}').DataTable({
44
- paging: #{setup.paging ? 'true' : 'false'} # rubocop:disable Rails/HelperInstanceVariable
45
- });
48
+ $('##{id}').DataTable({
49
+ paging: #{setup.paging ? 'true' : 'false'} # rubocop:disable Rails/HelperInstanceVariable
50
+ });
46
51
  });
47
52
  JS_CODE
48
53
  end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacRailsUtils
4
+ module LinksHelper
5
+ # @param object [Object]
6
+ # @param options [Hash] All the values are passed to the link_to method with except of:
7
+ # * :action : argument +action+ for the method +object_path+.
8
+ # * :blank_value : text used when +object+ is blank.
9
+ # * :confirm_translation: translation key for attribute +data.confirm+.
10
+ # * :name : argument +name+ for the method +link_to+.
11
+ # * :title_translation: translation key for attribute +title+.
12
+ # @return [ActiveSupport::SafeBuffer] The link or the blank_sign.
13
+ class ObjectLink
14
+ acts_as_instance_method
15
+ common_constructor :view, :object, :options, default: [{}]
16
+
17
+ NON_LINK_TO_OPTIONS = %i[action blank_value confirm_translation name title_translation].freeze
18
+
19
+ # @return [ActiveSupport::SafeBuffer]
20
+ def result
21
+ view.value_or_sign(object, blank_value) do |value|
22
+ view.link_to name, view.object_path(value, action), link_to_options
23
+ end
24
+ end
25
+
26
+ # @return [String, nil]
27
+ def action
28
+ options[:action]
29
+ end
30
+
31
+ # @return [String, nil]
32
+ def blank_value
33
+ options[:blank_value]
34
+ end
35
+
36
+ # @return [String, nil]
37
+ def confirm
38
+ options[:confirm_translation].if_present do |v|
39
+ ::I18n.t(v, label: object.to_s)
40
+ end
41
+ end
42
+
43
+ # @return [String, nil]
44
+ def name
45
+ options[:name] || object.to_s
46
+ end
47
+
48
+ # @return [String, nil]
49
+ def title
50
+ options[:title_translation].if_present do |v|
51
+ ::I18n.t(v, label: object.to_s)
52
+ end
53
+ end
54
+
55
+ protected
56
+
57
+ def apply_confirm(options)
58
+ confirm.if_present do |v|
59
+ options[:data] ||= {}
60
+ options[:data][:confirm] = v
61
+ end
62
+ end
63
+
64
+ def apply_title(options)
65
+ title.if_present do |v|
66
+ options[:title] = v
67
+ end
68
+ end
69
+
70
+ # @return [Hash]
71
+ def link_to_options
72
+ %w[confirm title].each_with_object(options.except(*NON_LINK_TO_OPTIONS)) do |e, a|
73
+ send("apply_#{e}", a)
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacRailsUtils
4
+ module LinksHelper
5
+ class ObjectPath
6
+ acts_as_instance_method
7
+ common_constructor :view, :object, :action, default: [nil]
8
+
9
+ def result
10
+ current_class = object_class(object)
11
+ tried_paths = []
12
+ while current_class
13
+ path = object_path_by_class(current_class, action)
14
+ return view.send(path, object) if view.respond_to?(path)
15
+
16
+ tried_paths << path
17
+ current_class = current_class.superclass
18
+ end
19
+ raise "Path not found for {object: #{object.class}, action: \"#{action}\"}" \
20
+ "(Tried: #{tried_paths})"
21
+ end
22
+
23
+ protected
24
+
25
+ def object_path_by_class(klass, action)
26
+ path = "#{klass.name.underscore.tr('/', '_')}_url"
27
+ path = "#{action}_#{path}" if action.present?
28
+ path
29
+ end
30
+
31
+ def object_class(object)
32
+ return object.entity_class if object.respond_to?(:entity_class)
33
+ return object.__getobj__.class if object.respond_to?(:__getobj__)
34
+
35
+ object.class
36
+ end
37
+ end
38
+ end
39
+ end
@@ -2,20 +2,37 @@
2
2
 
3
3
  module EacRailsUtils
4
4
  module LinksHelper
5
+ LINK_OPTIONS = { target: '_blank' }.freeze
6
+ SHORT_LINK_OPTIONS = LINK_OPTIONS.merge(name: '').freeze
7
+ DETAIL_LINK_OPTIONS = LINK_OPTIONS.merge(action: 'detail')
8
+ SHORT_DELETE_LINK_OPTIONS = SHORT_LINK_OPTIONS.merge(
9
+ action: '', class: 'delete_link', method: :delete,
10
+ title_translation: 'eac_rails_utils.links.delete_object',
11
+ confirm_translation: 'eac_rails_utils.links.delete_confirm'
12
+ ).freeze
13
+ SHORT_EDIT_LINK_OPTIONS = SHORT_LINK_OPTIONS.merge(
14
+ action: 'edit', class: 'edit_link', title_translation: 'eac_rails_utils.links.edit_object'
15
+ ).freeze
16
+ SHORT_DETAIL_SHOW_LINK_OPTIONS = SHORT_LINK_OPTIONS.merge(
17
+ class: 'show_link', title_translation: 'eac_rails_utils.links.show_object'
18
+ ).freeze
19
+ SHORT_DETAIL_LINK_OPTIONS = SHORT_DETAIL_SHOW_LINK_OPTIONS.merge(action: 'detail')
20
+ SHORT_SHOW_LINK_OPTIONS = SHORT_DETAIL_SHOW_LINK_OPTIONS.merge(action: '')
21
+ SHOW_LINK_OPTIONS = LINK_OPTIONS.merge(action: '')
22
+
23
+ # @param object [Object]
24
+ # @param options [Hash]
25
+ # @return [ActiveSupport::SafeBuffer]
26
+ def detail_link(object, **options)
27
+ object_link object, DETAIL_LINK_OPTIONS.merge(options)
28
+ end
29
+
5
30
  def short_delete_link(object)
6
- short_object_link object, '', class: 'delete_link', method: :delete, target: '_blank',
7
- title: ::I18n.t('eac_rails_utils.links.delete_object',
8
- label: object.to_s),
9
- data: {
10
- confirm: ::I18n.t('eac_rails_utils.links.delete_confirm',
11
- label: object.to_s)
12
- }
31
+ object_link object, SHORT_DELETE_LINK_OPTIONS
13
32
  end
14
33
 
15
34
  def short_edit_link(object)
16
- short_object_link object, 'edit', class: 'edit_link', target: '_blank',
17
- title: ::I18n.t('eac_rails_utils.links.edit_object',
18
- label: object.to_s)
35
+ object_link object, SHORT_EDIT_LINK_OPTIONS
19
36
  end
20
37
 
21
38
  def short_goto_link(url)
@@ -27,53 +44,20 @@ module EacRailsUtils
27
44
  end
28
45
 
29
46
  def short_show_link(object)
30
- short_detail_show_link(object, false)
47
+ object_link object, SHORT_SHOW_LINK_OPTIONS
31
48
  end
32
49
 
33
50
  def short_detail_link(object)
34
- short_detail_show_link(object, true)
35
- end
36
-
37
- def object_path(object, action = nil)
38
- current_class = object_class(object)
39
- tried_paths = []
40
- while current_class
41
- path = object_path_by_class(current_class, action)
42
- return send(path, object) if respond_to?(path)
43
-
44
- tried_paths << path
45
- current_class = current_class.superclass
46
- end
47
- raise "Path not found for {object: #{object.class}, action: \"#{action}\"}" \
48
- "(Tried: #{tried_paths})"
49
- end
50
-
51
- private
52
-
53
- def short_detail_show_link(object, detail)
54
- short_object_link object,
55
- detail ? 'detail' : nil,
56
- class: 'show_link', target: '_blank',
57
- title: ::I18n.t('eac_rails_utils.links.show_object', label: object.to_s)
51
+ object_link object, SHORT_DETAIL_LINK_OPTIONS
58
52
  end
59
53
 
60
- def short_object_link(object, action = nil, options = {})
61
- value_or_sign(object, '') do |value|
62
- link_to '', object_path(value, action), options
63
- end
54
+ # @param object [Object]
55
+ # @param options [Hash]
56
+ # @return [ActiveSupport::SafeBuffer]
57
+ def show_link(object, **options)
58
+ object_link object, SHOW_LINK_OPTIONS.merge(options)
64
59
  end
65
60
 
66
- def object_path_by_class(klass, action)
67
- path = "#{klass.name.underscore.tr('/', '_')}_url"
68
- path = "#{action}_#{path}" if action.present?
69
- path
70
- end
71
-
72
- def object_class(object)
73
- return object.entity_class if object.respond_to?(:entity_class)
74
- return object.__getobj__.class if object.respond_to?(:__getobj__)
75
-
76
- object.class
77
- end
61
+ require_sub __FILE__, require_mode: :kernel
78
62
  end
79
63
  end
@@ -85,7 +85,7 @@ module EacRailsUtils
85
85
  options[:method] = options[:link_method]
86
86
  options.delete(:link_method)
87
87
  end
88
- options[:class] = (@options[:button_class]).to_s.strip if entry[:level].zero? # rubocop:disable Rails/HelperInstanceVariable
88
+ options[:class] = @options[:button_class].to_s.strip if entry[:level].zero? # rubocop:disable Rails/HelperInstanceVariable
89
89
  options
90
90
  end
91
91
  end
@@ -1,6 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'eac_rails_utils/engine_helper'
3
+ require 'rails'
4
+ require 'active_model'
5
+ require 'active_record'
6
+ require 'virtus'
4
7
  require 'eac_rails_utils/patches'
5
8
  require 'nested_form_fields'
6
9
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'eac_ruby_utils/core_ext'
4
-
5
3
  module EacRailsUtils
6
4
  module EngineHelper
7
5
  class << self
@@ -30,9 +28,7 @@ module EacRailsUtils
30
28
  end
31
29
 
32
30
  # @return [EacRailsUtils::Menus::Group]
33
- def root_menu
34
- ::EacRailsUtils::EnginesHelper.root_menu
35
- end
31
+ delegate :root_menu, to: :'::EacRailsUtils::EnginesHelper'
36
32
  end
37
33
  end
38
34
  end
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'eac_rails_utils/menus/node'
4
- require 'eac_ruby_utils/core_ext'
5
-
6
3
  module EacRailsUtils
7
4
  module Menus
8
5
  class Action < ::EacRailsUtils::Menus::Node
@@ -1,9 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'eac_rails_utils/menus/action'
4
- require 'eac_rails_utils/menus/node'
5
- require 'eac_ruby_utils/core_ext'
6
-
7
3
  module EacRailsUtils
8
4
  module Menus
9
5
  class Group < ::EacRailsUtils::Menus::Node
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'eac_ruby_utils/core_ext'
4
-
5
3
  module EacRailsUtils
6
4
  module Menus
7
5
  class Node
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'eac_ruby_utils/core_ext'
4
-
5
3
  module EacRailsUtils
6
4
  module Menus
7
5
  require_sub __FILE__
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'eac_ruby_utils/core_ext'
4
-
5
3
  module EacRailsUtils
6
4
  module Models
7
5
  class Tableless
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'eac_ruby_utils/core_ext'
4
-
5
3
  module EacRailsUtils
6
4
  module Models
7
5
  class Tableless
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'eac_ruby_utils/core_ext'
4
-
5
3
  module EacRailsUtils
6
4
  module Models
7
5
  class Tableless
@@ -16,9 +14,7 @@ module EacRailsUtils
16
14
  end
17
15
 
18
16
  # @return [Boolean]
19
- def strict_loading?
20
- self.class.strict_loading?
21
- end
17
+ delegate :strict_loading?, to: :class
22
18
  end
23
19
  end
24
20
  end
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'eac_rails_utils/patches/active_model_associations'
4
- require 'virtus'
5
-
6
3
  module EacRailsUtils
7
4
  module Models
8
5
  class Tableless
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_record/associations/builder/has_many'
4
+
5
+ module EacRailsUtils
6
+ module Models
7
+ module TablelessAssociations
8
+ class HasManyForActiveModel < ::ActiveRecord::Associations::Builder::HasMany
9
+ if ActiveRecord.version >= Gem::Version.new('5.0.0.beta')
10
+ AR_CALLBACK_METHODS = %i[define_callback before_validation after_validation before_save
11
+ after_save before_update after_update].freeze
12
+
13
+ def self.valid_options(_options)
14
+ super + %i[active_model
15
+ target_ids] - %i[through dependent source source_type counter_cache as]
16
+ end
17
+
18
+ def self.define_callbacks(model, reflection)
19
+ return unless AR_CALLBACK_METHODS.all? { |meth| respond_to?(meth) }
20
+
21
+ super
22
+ end
23
+ else
24
+ def valid_options
25
+ super + %i[active_model
26
+ target_ids] - %i[through dependent source source_type counter_cache as]
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacRailsUtils
4
+ module Models
5
+ module TablelessAssociations
6
+ class HasManyForActiveModelAssociation < ActiveRecord::Associations::HasManyAssociation
7
+ # remove conditions: owner.new_record?, foreign_key_present?
8
+ def find_target?
9
+ !loaded? && klass
10
+ end
11
+
12
+ # no dependent action
13
+ def null_scope?
14
+ false
15
+ end
16
+
17
+ # not support counter_cache
18
+ def empty?
19
+ if loaded?
20
+ size.zero?
21
+ else
22
+ @target.blank? && !scope.exists?
23
+ end
24
+ end
25
+
26
+ # full replace simplely
27
+ def replace(other_array) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
28
+ original_target = load_target.dup
29
+ other_array.each { |val| raise_on_type_mismatch!(val) }
30
+ target_ids = reflection.options[:target_ids]
31
+ owner[target_ids] = other_array.map(&:id)
32
+
33
+ old_records = original_target - other_array
34
+ old_records.each do |record|
35
+ @target.delete(record)
36
+ end
37
+
38
+ other_array.each do |record|
39
+ if (index = @target.index(record))
40
+ @target[index] = record
41
+ else
42
+ @target << record
43
+ end
44
+ end
45
+ end
46
+
47
+ # no need transaction
48
+ def concat(*records) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
49
+ load_target
50
+ flatten_records = records.flatten
51
+ flatten_records.each { |val| raise_on_type_mismatch!(val) }
52
+ target_ids = reflection.options[:target_ids]
53
+ owner[target_ids] ||= []
54
+ owner[target_ids].concat(flatten_records.map(&:id))
55
+
56
+ flatten_records.each do |record|
57
+ if (index = @target.index(record))
58
+ @target[index] = record
59
+ else
60
+ @target << record
61
+ end
62
+ end
63
+
64
+ target
65
+ end
66
+
67
+ private
68
+
69
+ def get_records # rubocop:disable Naming/AccessorMethodName
70
+ return scope.to_a if reflection.scope_chain.any?(&:any?)
71
+
72
+ target_ids = reflection.options[:target_ids]
73
+ klass.where(id: owner[target_ids]).to_a
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -6,7 +6,6 @@ module EacRailsUtils
6
6
  module Hooks
7
7
  def self.init
8
8
  ActiveSupport.on_load(:active_record) do
9
- require 'eac_rails_utils/models/tableless_associations/association_scope_extension'
10
9
  ActiveRecord::Associations::AssociationScope.prepend(
11
10
  EacRailsUtils::Models::TablelessAssociations::AssociationScopeExtension
12
11
  )
@@ -97,7 +97,9 @@ module EacRailsUtils
97
97
  def association_by_reflection(name)
98
98
  reflection = self.class.reflect_on_association(name)
99
99
  if reflection.options[:active_model]
100
- ::ActiveRecord::Associations::HasManyForActiveModelAssociation.new(self, reflection)
100
+ ::EacRailsUtils::Models::TablelessAssociations::HasManyForActiveModelAssociation.new(
101
+ self, reflection
102
+ )
101
103
  else
102
104
  reflection.association_class.new(self, reflection)
103
105
  end
@@ -1,11 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'eac_rails_utils/models/tableless_associations/initialize_extension'
4
- require 'eac_rails_utils/models/tableless_associations/active_record_reflection'
5
- require 'eac_rails_utils/models/tableless_associations/autosave_association'
6
- require 'eac_rails_utils/models/tableless_associations/override_methods'
7
- require 'active_record/associations/builder/has_many_for_active_model'
8
- require 'active_record/associations/has_many_for_active_model_association'
9
3
  require 'active_support/core_ext/module'
10
4
 
11
5
  module EacRailsUtils
@@ -31,14 +25,14 @@ module EacRailsUtils
31
25
  end
32
26
 
33
27
  # define association like ActiveRecord
34
- def has_many(name, scope = nil, **options, &extension) # rubocop:disable Naming/PredicateName, Metrics/MethodLength
28
+ def has_many(name, scope = nil, **options, &extension) # rubocop:disable Metrics/MethodLength, Naming/PredicatePrefix
35
29
  options.reverse_merge!(active_model: true, target_ids: "#{name.to_s.singularize}_ids")
36
30
  if scope.is_a?(Hash)
37
31
  options.merge!(scope)
38
32
  scope = nil
39
33
  end
40
34
 
41
- reflection = ActiveRecord::Associations::Builder::HasManyForActiveModel
35
+ reflection = EacRailsUtils::Models::TablelessAssociations::HasManyForActiveModel
42
36
  .build(self, name, scope, options, &extension)
43
37
  ActiveRecord::Reflection.add_reflection self, name, reflection
44
38
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'eac_ruby_utils/core_ext'
4
-
5
3
  module EacRailsUtils
6
4
  module Models
7
5
  module Validations
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'eac_ruby_utils/require_sub'
4
-
5
3
  module EacRailsUtils
6
4
  module Models
7
5
  ::EacRubyUtils.require_sub __FILE__
@@ -1,4 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'eac_ruby_utils/require_sub'
4
3
  EacRubyUtils.require_sub __FILE__
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'activemodel/associations'
4
- require 'eac_rails_utils/patches/rails_5_2'
5
-
6
3
  module EacRailsUtils
7
4
  module Models
8
5
  module TablelessAssociations
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'eac_rails_utils/menus/group'
4
-
5
3
  module Rails
6
4
  class Application
7
5
  # @return [EacRailsUtils::Menus::Group]
@@ -23,9 +23,7 @@ class Numeric
23
23
  end
24
24
 
25
25
  # @return [Object] A object that extends [ActionView::Helpers::NumberHelper]
26
- def number_helper
27
- self.class.number_helper
28
- end
26
+ delegate :number_helper, to: :class
29
27
 
30
28
  # @return [String]
31
29
  def to_currency(options = {})
@@ -59,6 +57,6 @@ class Numeric
59
57
 
60
58
  # @return [String]
61
59
  def with_precision(options = {})
62
- number_helper.number_with_precision(self, default_precision_options(options).print_debug)
60
+ number_helper.number_with_precision(self, default_precision_options(options))
63
61
  end
64
62
  end
@@ -1,4 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'eac_ruby_utils/require_sub'
4
3
  EacRubyUtils.require_sub __FILE__
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'activemodel/associations'
4
- require 'eac_ruby_utils/core_ext'
5
-
6
3
  module EacRailsUtils
7
4
  module Patches
8
5
  module Rails52
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'eac_rails_utils/models/tableless_associations/hooks'
4
- require 'eac_ruby_utils/require_sub'
5
-
6
3
  module EacRailsUtils
7
4
  module Patches
8
5
  module Rails52
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'eac_ruby_utils/require_sub'
4
-
5
3
  module EacRailsUtils
6
4
  module Patches
7
5
  ::EacRubyUtils.require_sub __FILE__
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'eac_ruby_utils/core_ext'
4
-
5
3
  module EacRailsUtils
6
4
  module Rspec
7
5
  module Setup
@@ -12,7 +10,7 @@ module EacRailsUtils
12
10
  send(record_variable).send("#{attribute}=", value)
13
11
  end
14
12
 
15
- it "#{record_variable} should be #{valid ? '' : 'not '}valid" do
13
+ it "#{record_variable} should be #{'not ' unless valid}valid" do
16
14
  expect(send(record_variable).valid?).to(send("be_#{valid ? 'truthy' : 'falsy'}"),
17
15
  -> { send(record_variable).errors.messages })
18
16
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'eac_ruby_utils/core_ext'
4
-
5
3
  module EacRailsUtils
6
4
  module Rspec
7
5
  module Setup
@@ -2,7 +2,6 @@
2
2
 
3
3
  module EacRailsUtils
4
4
  module Rspec
5
- require 'eac_ruby_utils/require_sub'
6
5
  ::EacRubyUtils.require_sub(__FILE__)
7
6
  end
8
7
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module EacRailsUtils
4
- VERSION = '0.24.0'
4
+ VERSION = '0.26.0'
5
5
  end
@@ -1,7 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'eac_ruby_utils/require_sub'
3
+ require 'eac_ruby_utils'
4
+ EacRubyUtils::RootModuleSetup.perform __FILE__ do
5
+ ignore 'patches'
6
+ end
4
7
 
5
8
  module EacRailsUtils
6
- ::EacRubyUtils.require_sub __FILE__
7
9
  end
10
+
11
+ require 'rails'
12
+
13
+ require 'eac_rails_utils/engine'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eac_rails_utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.24.0
4
+ version: 0.26.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - E.A.C.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-07-05 00:00:00.000000000 Z
11
+ date: 2025-07-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bootstrap-sass
@@ -36,14 +36,14 @@ dependencies:
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: '0.122'
39
+ version: '0.128'
40
40
  type: :runtime
41
41
  prerelease: false
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: '0.122'
46
+ version: '0.128'
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rails
49
49
  requirement: !ruby/object:Gem::Requirement
@@ -98,20 +98,14 @@ dependencies:
98
98
  requirements:
99
99
  - - "~>"
100
100
  - !ruby/object:Gem::Version
101
- version: '0.10'
102
- - - ">="
103
- - !ruby/object:Gem::Version
104
- version: 0.10.1
101
+ version: '0.11'
105
102
  type: :development
106
103
  prerelease: false
107
104
  version_requirements: !ruby/object:Gem::Requirement
108
105
  requirements:
109
106
  - - "~>"
110
107
  - !ruby/object:Gem::Version
111
- version: '0.10'
112
- - - ">="
113
- - !ruby/object:Gem::Version
114
- version: 0.10.1
108
+ version: '0.11'
115
109
  description:
116
110
  email:
117
111
  executables: []
@@ -159,6 +153,8 @@ files:
159
153
  - app/helpers/eac_rails_utils/data_table_helper/setup.rb
160
154
  - app/helpers/eac_rails_utils/formatter_helper.rb
161
155
  - app/helpers/eac_rails_utils/links_helper.rb
156
+ - app/helpers/eac_rails_utils/links_helper/object_link.rb
157
+ - app/helpers/eac_rails_utils/links_helper/object_path.rb
162
158
  - app/helpers/eac_rails_utils/menus_helper.rb
163
159
  - app/helpers/eac_rails_utils/menus_helper/bootstrap_gui_builder.rb
164
160
  - app/helpers/eac_rails_utils/menus_helper/data_builder.rb
@@ -172,9 +168,6 @@ files:
172
168
  - config/initializers/json.rb
173
169
  - config/locales/en.yml
174
170
  - config/locales/pt-BR.yml
175
- - lib/active_record/associations/builder/has_many_for_active_model.rb
176
- - lib/active_record/associations/has_many_for_active_model_association.rb
177
- - lib/activemodel/associations.rb
178
171
  - lib/eac_rails_utils.rb
179
172
  - lib/eac_rails_utils/engine.rb
180
173
  - lib/eac_rails_utils/engine_helper.rb
@@ -194,6 +187,8 @@ files:
194
187
  - lib/eac_rails_utils/models/tableless_associations/active_record_reflection.rb
195
188
  - lib/eac_rails_utils/models/tableless_associations/association_scope_extension.rb
196
189
  - lib/eac_rails_utils/models/tableless_associations/autosave_association.rb
190
+ - lib/eac_rails_utils/models/tableless_associations/has_many_for_active_model.rb
191
+ - lib/eac_rails_utils/models/tableless_associations/has_many_for_active_model_association.rb
197
192
  - lib/eac_rails_utils/models/tableless_associations/hooks.rb
198
193
  - lib/eac_rails_utils/models/tableless_associations/initialize_extension.rb
199
194
  - lib/eac_rails_utils/models/tableless_associations/override_methods.rb
@@ -1,24 +0,0 @@
1
- module ActiveRecord::Associations::Builder # rubocop:disable Style/ClassAndModuleChildren, Style/FrozenStringLiteralComment
2
- class HasManyForActiveModel < HasMany
3
- if ActiveRecord.version >= Gem::Version.new('5.0.0.beta')
4
- AR_CALLBACK_METHODS = %i[define_callback before_validation after_validation before_save
5
- after_save before_update after_update].freeze
6
-
7
- def self.valid_options(_options)
8
- super + %i[active_model
9
- target_ids] - %i[through dependent source source_type counter_cache as]
10
- end
11
-
12
- def self.define_callbacks(model, reflection)
13
- return unless AR_CALLBACK_METHODS.all? { |meth| respond_to?(meth) }
14
-
15
- super
16
- end
17
- else
18
- def valid_options
19
- super + %i[active_model
20
- target_ids] - %i[through dependent source source_type counter_cache as]
21
- end
22
- end
23
- end
24
- end
@@ -1,72 +0,0 @@
1
- module ActiveRecord::Associations # rubocop:disable Style/ClassAndModuleChildren, Style/FrozenStringLiteralComment
2
- class HasManyForActiveModelAssociation < HasManyAssociation
3
- # remove conditions: owner.new_record?, foreign_key_present?
4
- def find_target?
5
- !loaded? && klass
6
- end
7
-
8
- # no dependent action
9
- def null_scope?
10
- false
11
- end
12
-
13
- # not support counter_cache
14
- def empty?
15
- if loaded?
16
- size.zero?
17
- else
18
- @target.blank? && !scope.exists?
19
- end
20
- end
21
-
22
- # full replace simplely
23
- def replace(other_array) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
24
- original_target = load_target.dup
25
- other_array.each { |val| raise_on_type_mismatch!(val) }
26
- target_ids = reflection.options[:target_ids]
27
- owner[target_ids] = other_array.map(&:id)
28
-
29
- old_records = original_target - other_array
30
- old_records.each do |record|
31
- @target.delete(record)
32
- end
33
-
34
- other_array.each do |record|
35
- if (index = @target.index(record))
36
- @target[index] = record
37
- else
38
- @target << record
39
- end
40
- end
41
- end
42
-
43
- # no need transaction
44
- def concat(*records) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
45
- load_target
46
- flatten_records = records.flatten
47
- flatten_records.each { |val| raise_on_type_mismatch!(val) }
48
- target_ids = reflection.options[:target_ids]
49
- owner[target_ids] ||= []
50
- owner[target_ids].concat(flatten_records.map(&:id))
51
-
52
- flatten_records.each do |record|
53
- if (index = @target.index(record))
54
- @target[index] = record
55
- else
56
- @target << record
57
- end
58
- end
59
-
60
- target
61
- end
62
-
63
- private
64
-
65
- def get_records # rubocop:disable Naming/AccessorMethodName
66
- return scope.to_a if reflection.scope_chain.any?(&:any?)
67
-
68
- target_ids = reflection.options[:target_ids]
69
- klass.where(id: owner[target_ids]).to_a
70
- end
71
- end
72
- end
@@ -1,13 +0,0 @@
1
- require 'active_model' # rubocop:disable Style/FrozenStringLiteralComment
2
- require 'active_record'
3
- require 'active_support'
4
- require 'eac_rails_utils/models/tableless_associations'
5
- require 'eac_rails_utils/models/tableless_associations/hooks'
6
-
7
- # Load Railtie
8
- begin
9
- require 'rails'
10
- rescue LoadError # rubocop:disable Lint/SuppressedException
11
- end
12
-
13
- require 'eac_rails_utils/models/tableless_associations/railtie' if defined?(Rails)