forest_admin_datasource_active_record 1.0.0.pre.beta.61 → 1.0.0.pre.beta.62

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c9ce7a6a32ae3e985c64e2c9458165de5d24e8d7a532ca6a405aac048ef5ede8
4
- data.tar.gz: 65ba39d8d70775cbb98e4b0f0d85888a5946fda8e34bd88bb8e7e3b52004fe2c
3
+ metadata.gz: 768aba915cd8fc48929a8bdc08fdf81dd735aa9b6d8d7f2a7f2ecb4c99c4e854
4
+ data.tar.gz: 32a0e8e3b7468dd6ec2244ea1b59da6383af8f36f48b4c5d7025094550612eca
5
5
  SHA512:
6
- metadata.gz: 2a1fcf17fd734b4275c86f82ac5afb4ff03bb4ac5a52b556b2df3ef1407f38076b37c94d650923711e0fe56fb63455e80ad1713c403592a93501b54e088b595b
7
- data.tar.gz: 112af29e8fab7793768607f64e5f51c97183623cf461f8fcd24f332267d40d5bb62b04e2cc73115e2c0b7f10f239a1d97cc82023cf09646d78de40c5c0cfaff2
6
+ metadata.gz: 7cea2e22bccfce7e48423cce3656b9457cea8882721bb6f39dc6ca44b7edc8fefcb9f0b8bde0226f33fa3ae5dcaae0b5d23113eeb92e6ef9e71793d70c427fb1
7
+ data.tar.gz: 7a015c989b6183d4a97c8d95f1f614b7a6fa58d64e2a498072e246218e6398040e22ec7098bc260ee8cc045119adf8155a64063cad007ad5f0c8ee93869979e6
@@ -6,9 +6,10 @@ module ForestAdminDatasourceActiveRecord
6
6
 
7
7
  attr_reader :model
8
8
 
9
- def initialize(datasource, model)
9
+ def initialize(datasource, model, support_polymorphic_relations: false)
10
10
  @model = model
11
- name = model.name.demodulize.underscore
11
+ @support_polymorphic_relations = support_polymorphic_relations
12
+ name = format_model_name(@model.name)
12
13
  super(datasource, name)
13
14
  fetch_fields
14
15
  fetch_associations
@@ -35,7 +36,7 @@ module ForestAdminDatasourceActiveRecord
35
36
 
36
37
  def update(_caller, filter, data)
37
38
  entity = Utils::Query.new(self, nil, filter).build.first
38
- entity.update(data)
39
+ entity&.update(data)
39
40
  end
40
41
 
41
42
  def delete(_caller, filter)
@@ -45,6 +46,10 @@ module ForestAdminDatasourceActiveRecord
45
46
 
46
47
  private
47
48
 
49
+ def format_model_name(class_name)
50
+ class_name.gsub('::', '__')
51
+ end
52
+
48
53
  def fetch_fields
49
54
  @model.columns_hash.each do |column_name, column|
50
55
  field = ForestAdminDatasourceToolkit::Schema::ColumnSchema.new(
@@ -66,11 +71,11 @@ module ForestAdminDatasourceActiveRecord
66
71
  def association_primary_key?(association)
67
72
  !association.association_primary_key.empty?
68
73
  rescue StandardError
69
- false
74
+ association.polymorphic?
70
75
  end
71
76
 
72
77
  def fetch_associations
73
- associations(@model).each do |association|
78
+ associations(@model, support_polymorphic_relations: @support_polymorphic_relations).each do |association|
74
79
  case association.macro
75
80
  when :has_one
76
81
  if association_primary_key?(association)
@@ -78,19 +83,30 @@ module ForestAdminDatasourceActiveRecord
78
83
  add_field(
79
84
  association.name.to_s,
80
85
  ForestAdminDatasourceToolkit::Schema::Relations::ManyToManySchema.new(
81
- foreign_collection: association.class_name.demodulize.underscore,
86
+ foreign_collection: format_model_name(association.klass.name),
82
87
  origin_key: association.through_reflection.foreign_key,
83
88
  origin_key_target: association.through_reflection.join_foreign_key,
84
89
  foreign_key: association.join_foreign_key,
85
90
  foreign_key_target: association.association_primary_key,
86
- through_collection: association.through_reflection.class_name.demodulize.underscore
91
+ through_collection: format_model_name(association.through_reflection.klass.name)
92
+ )
93
+ )
94
+ elsif association.inverse_of.polymorphic?
95
+ add_field(
96
+ association.name.to_s,
97
+ ForestAdminDatasourceToolkit::Schema::Relations::PolymorphicOneToOneSchema.new(
98
+ foreign_collection: format_model_name(association.klass.name),
99
+ origin_key: association.foreign_key,
100
+ origin_key_target: association.association_primary_key,
101
+ origin_type_field: association.inverse_of.foreign_type,
102
+ origin_type_value: @model.name
87
103
  )
88
104
  )
89
105
  else
90
106
  add_field(
91
107
  association.name.to_s,
92
108
  ForestAdminDatasourceToolkit::Schema::Relations::OneToOneSchema.new(
93
- foreign_collection: association.class_name.demodulize.underscore,
109
+ foreign_collection: format_model_name(association.klass.name),
94
110
  origin_key: association.foreign_key,
95
111
  origin_key_target: association.association_primary_key
96
112
  )
@@ -99,14 +115,29 @@ module ForestAdminDatasourceActiveRecord
99
115
  end
100
116
  when :belongs_to
101
117
  if association_primary_key?(association)
102
- add_field(
103
- association.name.to_s,
104
- ForestAdminDatasourceToolkit::Schema::Relations::ManyToOneSchema.new(
105
- foreign_collection: association.class_name.demodulize.underscore,
106
- foreign_key: association.foreign_key,
107
- foreign_key_target: association.association_primary_key
118
+ if polymorphic?(association)
119
+ foreign_collections = get_polymorphic_types(association)
120
+ add_field(
121
+ association.name.to_s,
122
+ ForestAdminDatasourceToolkit::Schema::Relations::PolymorphicManyToOneSchema.new(
123
+ foreign_collections: foreign_collections.keys,
124
+ foreign_key: association.foreign_key,
125
+ foreign_key_type_field: association.foreign_type,
126
+ foreign_key_targets: foreign_collections
127
+ )
108
128
  )
109
- )
129
+ schema[:fields][association.foreign_key].is_read_only = true
130
+ schema[:fields][association.foreign_type].is_read_only = true
131
+ else
132
+ add_field(
133
+ association.name.to_s,
134
+ ForestAdminDatasourceToolkit::Schema::Relations::ManyToOneSchema.new(
135
+ foreign_collection: format_model_name(association.klass.name),
136
+ foreign_key: association.foreign_key,
137
+ foreign_key_target: association.association_primary_key
138
+ )
139
+ )
140
+ end
110
141
  end
111
142
  when :has_many
112
143
  if association_primary_key?(association)
@@ -114,19 +145,30 @@ module ForestAdminDatasourceActiveRecord
114
145
  add_field(
115
146
  association.name.to_s,
116
147
  ForestAdminDatasourceToolkit::Schema::Relations::ManyToManySchema.new(
117
- foreign_collection: association.class_name.demodulize.underscore,
148
+ foreign_collection: format_model_name(association.klass.name),
118
149
  origin_key: association.through_reflection.foreign_key,
119
150
  origin_key_target: association.through_reflection.join_foreign_key,
120
151
  foreign_key: association.join_foreign_key,
121
152
  foreign_key_target: association.association_primary_key,
122
- through_collection: association.through_reflection.class_name.demodulize.underscore
153
+ through_collection: format_model_name(association.through_reflection.klass.name)
154
+ )
155
+ )
156
+ elsif association.inverse_of.polymorphic?
157
+ add_field(
158
+ association.name.to_s,
159
+ ForestAdminDatasourceToolkit::Schema::Relations::PolymorphicOneToManySchema.new(
160
+ foreign_collection: format_model_name(association.klass.name),
161
+ origin_key: association.foreign_key,
162
+ origin_key_target: association.association_primary_key,
163
+ origin_type_field: association.inverse_of.foreign_type,
164
+ origin_type_value: @model.name
123
165
  )
124
166
  )
125
167
  else
126
168
  add_field(
127
169
  association.name.to_s,
128
170
  ForestAdminDatasourceToolkit::Schema::Relations::OneToManySchema.new(
129
- foreign_collection: association.class_name.demodulize.underscore,
171
+ foreign_collection: format_model_name(association.klass.name),
130
172
  origin_key: association.foreign_key,
131
173
  origin_key_target: association.association_primary_key
132
174
  )
@@ -2,9 +2,12 @@ require 'active_record'
2
2
 
3
3
  module ForestAdminDatasourceActiveRecord
4
4
  class Datasource < ForestAdminDatasourceToolkit::Datasource
5
- def initialize(db_config = {})
5
+ attr_reader :models
6
+
7
+ def initialize(db_config = {}, support_polymorphic_relations: false)
6
8
  super()
7
9
  @models = []
10
+ @support_polymorphic_relations = support_polymorphic_relations
8
11
  @habtm_models = {}
9
12
  init_orm(db_config)
10
13
  generate
@@ -15,7 +18,9 @@ module ForestAdminDatasourceActiveRecord
15
18
  def generate
16
19
  ActiveRecord::Base.descendants.each { |model| fetch_model(model) }
17
20
  @models.each do |model|
18
- add_collection(Collection.new(self, model))
21
+ add_collection(
22
+ Collection.new(self, model, support_polymorphic_relations: @support_polymorphic_relations)
23
+ )
19
24
  end
20
25
  end
21
26
 
@@ -1,14 +1,19 @@
1
1
  module ForestAdminDatasourceActiveRecord
2
2
  module Parser
3
3
  module Relation
4
- def associations(model)
4
+ def associations(model, support_polymorphic_relations: false)
5
5
  model.reflect_on_all_associations.select do |association|
6
- !polymorphic?(association) && !active_type?(association.klass)
6
+ if support_polymorphic_relations
7
+ polymorphic?(association) ? true : !active_type?(association.klass)
8
+ else
9
+ !polymorphic?(association) && !active_type?(association.klass)
10
+ end
7
11
  end
8
12
  end
9
13
 
10
14
  def polymorphic?(association)
11
- association.options[:polymorphic]
15
+ (association.options.key?(:polymorphic) && association.options[:polymorphic]) ||
16
+ association.inverse_of&.polymorphic?
12
17
  end
13
18
 
14
19
  # NOTICE: Ignores ActiveType::Object association during introspection and interactions.
@@ -16,6 +21,17 @@ module ForestAdminDatasourceActiveRecord
16
21
  def active_type?(model)
17
22
  Object.const_defined?('ActiveType::Object') && model < ActiveType::Object
18
23
  end
24
+
25
+ def get_polymorphic_types(relation)
26
+ types = {}
27
+ @datasource.models.each do |model|
28
+ unless model.reflect_on_all_associations.none? { |assoc| assoc.options[:as] == relation.name.to_sym }
29
+ types[format_model_name(model.name)] = model.primary_key
30
+ end
31
+ end
32
+
33
+ types
34
+ end
19
35
  end
20
36
  end
21
37
  end
@@ -13,7 +13,7 @@ module ForestAdminDatasourceActiveRecord
13
13
  hash.merge! object.attributes
14
14
 
15
15
  if with_associations
16
- each_association_collection(object) do |association_name, item|
16
+ each_association_collection(object, projection) do |association_name, item|
17
17
  hash[association_name] = hash_object(
18
18
  item,
19
19
  projection.relations[association_name],
@@ -25,9 +25,10 @@ module ForestAdminDatasourceActiveRecord
25
25
  hash
26
26
  end
27
27
 
28
- def each_association_collection(object)
28
+ def each_association_collection(object, projection)
29
29
  one_associations = %i[has_one belongs_to]
30
- object.class.reflect_on_all_associations.filter { |a| one_associations.include?(a.macro) }
30
+ object.class.reflect_on_all_associations
31
+ .filter { |a| one_associations.include?(a.macro) && projection.relations.key?(a.name.to_s) }
31
32
  .each { |association| yield(association.name.to_s, object.send(association.name.to_s)) }
32
33
  end
33
34
  end
@@ -123,14 +123,11 @@ module ForestAdminDatasourceActiveRecord
123
123
  end
124
124
 
125
125
  def format_field(field)
126
- @select << "#{@collection.model.table_name}.#{field}"
127
-
128
126
  if field.include?(':')
129
127
  relation_name, field = field.split(':')
130
128
  relation = @collection.schema[:fields][relation_name]
131
129
  table_name = @collection.datasource.get_collection(relation.foreign_collection).model.table_name
132
130
  add_join_relation(relation_name)
133
- @select << "#{table_name}.#{field}"
134
131
 
135
132
  return "#{table_name}.#{field}"
136
133
  end
@@ -1,3 +1,3 @@
1
1
  module ForestAdminDatasourceActiveRecord
2
- VERSION = "1.0.0-beta.61"
2
+ VERSION = "1.0.0-beta.62"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: forest_admin_datasource_active_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.pre.beta.61
4
+ version: 1.0.0.pre.beta.62
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthieu
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2024-07-26 00:00:00.000000000 Z
12
+ date: 2024-08-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord