eac_rails_utils 0.24.0 → 0.25.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.
- checksums.yaml +4 -4
- data/app/helpers/eac_rails_utils/data_table_helper/data_table.rb +10 -5
- data/app/helpers/eac_rails_utils/links_helper/object_link.rb +78 -0
- data/app/helpers/eac_rails_utils/links_helper/object_path.rb +39 -0
- data/app/helpers/eac_rails_utils/links_helper.rb +35 -51
- data/lib/eac_rails_utils/models/tableless_associations/has_many_for_active_model.rb +32 -0
- data/lib/eac_rails_utils/models/tableless_associations/has_many_for_active_model_association.rb +78 -0
- data/lib/eac_rails_utils/models/tableless_associations/override_methods.rb +3 -1
- data/lib/eac_rails_utils/models/tableless_associations.rb +3 -3
- data/lib/eac_rails_utils/patches/active_model_associations.rb +0 -1
- data/lib/eac_rails_utils/patches/rails_5_2/active_model_association_method_fix.rb +2 -1
- data/lib/eac_rails_utils/version.rb +1 -1
- metadata +8 -7
- data/lib/active_record/associations/builder/has_many_for_active_model.rb +0 -24
- data/lib/active_record/associations/has_many_for_active_model_association.rb +0 -72
- data/lib/activemodel/associations.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0b5ed5306142ed06d984e58c9e16e743eeb1553e0aeb71d20b0a74eedb184edb
|
4
|
+
data.tar.gz: 47b1a51b701dc1edcba208f0d67104e5b72cdfc64c147c734bf8c7578b302377
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed95ae67b0db7fea40dd3524f23dc1673b59b49a7058d76624f5094f541908997ebde03869c4f348dd31b743a4b6b8a94467388a5daa4895333ba326e9ba3a53
|
7
|
+
data.tar.gz: 98bf0813f2b764a5d5148afda0c024de7110b66f70322aec8e1a45fd4df2e9f3266541d46b8af59384a2d6856fe0901ca8d183cae7b16bea14bd717ca1914606
|
@@ -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(:
|
12
|
-
|
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
|
-
|
44
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
47
|
+
object_link object, SHORT_SHOW_LINK_OPTIONS
|
31
48
|
end
|
32
49
|
|
33
50
|
def short_detail_link(object)
|
34
|
-
|
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
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
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
|
-
|
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
|
@@ -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
|
data/lib/eac_rails_utils/models/tableless_associations/has_many_for_active_model_association.rb
ADDED
@@ -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
|
@@ -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
|
-
::
|
100
|
+
::EacRailsUtils::Models::TablelessAssociations::HasManyForActiveModelAssociation.new(
|
101
|
+
self, reflection
|
102
|
+
)
|
101
103
|
else
|
102
104
|
reflection.association_class.new(self, reflection)
|
103
105
|
end
|
@@ -4,8 +4,8 @@ require 'eac_rails_utils/models/tableless_associations/initialize_extension'
|
|
4
4
|
require 'eac_rails_utils/models/tableless_associations/active_record_reflection'
|
5
5
|
require 'eac_rails_utils/models/tableless_associations/autosave_association'
|
6
6
|
require 'eac_rails_utils/models/tableless_associations/override_methods'
|
7
|
-
require '
|
8
|
-
require '
|
7
|
+
require 'eac_rails_utils/models/tableless_associations/has_many_for_active_model'
|
8
|
+
require 'eac_rails_utils/models/tableless_associations/has_many_for_active_model_association'
|
9
9
|
require 'active_support/core_ext/module'
|
10
10
|
|
11
11
|
module EacRailsUtils
|
@@ -38,7 +38,7 @@ module EacRailsUtils
|
|
38
38
|
scope = nil
|
39
39
|
end
|
40
40
|
|
41
|
-
reflection =
|
41
|
+
reflection = EacRailsUtils::Models::TablelessAssociations::HasManyForActiveModel
|
42
42
|
.build(self, name, scope, options, &extension)
|
43
43
|
ActiveRecord::Reflection.add_reflection self, name, reflection
|
44
44
|
|
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.
|
4
|
+
version: 0.25.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-
|
11
|
+
date: 2024-10-29 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.
|
39
|
+
version: '0.123'
|
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.
|
46
|
+
version: '0.123'
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rails
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -159,6 +159,8 @@ files:
|
|
159
159
|
- app/helpers/eac_rails_utils/data_table_helper/setup.rb
|
160
160
|
- app/helpers/eac_rails_utils/formatter_helper.rb
|
161
161
|
- app/helpers/eac_rails_utils/links_helper.rb
|
162
|
+
- app/helpers/eac_rails_utils/links_helper/object_link.rb
|
163
|
+
- app/helpers/eac_rails_utils/links_helper/object_path.rb
|
162
164
|
- app/helpers/eac_rails_utils/menus_helper.rb
|
163
165
|
- app/helpers/eac_rails_utils/menus_helper/bootstrap_gui_builder.rb
|
164
166
|
- app/helpers/eac_rails_utils/menus_helper/data_builder.rb
|
@@ -172,9 +174,6 @@ files:
|
|
172
174
|
- config/initializers/json.rb
|
173
175
|
- config/locales/en.yml
|
174
176
|
- 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
177
|
- lib/eac_rails_utils.rb
|
179
178
|
- lib/eac_rails_utils/engine.rb
|
180
179
|
- lib/eac_rails_utils/engine_helper.rb
|
@@ -194,6 +193,8 @@ files:
|
|
194
193
|
- lib/eac_rails_utils/models/tableless_associations/active_record_reflection.rb
|
195
194
|
- lib/eac_rails_utils/models/tableless_associations/association_scope_extension.rb
|
196
195
|
- lib/eac_rails_utils/models/tableless_associations/autosave_association.rb
|
196
|
+
- lib/eac_rails_utils/models/tableless_associations/has_many_for_active_model.rb
|
197
|
+
- lib/eac_rails_utils/models/tableless_associations/has_many_for_active_model_association.rb
|
197
198
|
- lib/eac_rails_utils/models/tableless_associations/hooks.rb
|
198
199
|
- lib/eac_rails_utils/models/tableless_associations/initialize_extension.rb
|
199
200
|
- 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)
|