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

Sign up to get free protection for your applications and to get access to all the features.
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