forest_admin_datasource_active_record 1.0.0.pre.beta.60 → 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 +4 -4
- data/lib/forest_admin_datasource_active_record/collection.rb +108 -40
- data/lib/forest_admin_datasource_active_record/datasource.rb +17 -3
- data/lib/forest_admin_datasource_active_record/parser/relation.rb +19 -3
- data/lib/forest_admin_datasource_active_record/utils/active_record_serializer.rb +4 -3
- data/lib/forest_admin_datasource_active_record/utils/query.rb +0 -3
- data/lib/forest_admin_datasource_active_record/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 768aba915cd8fc48929a8bdc08fdf81dd735aa9b6d8d7f2a7f2ecb4c99c4e854
|
4
|
+
data.tar.gz: 32a0e8e3b7468dd6ec2244ea1b59da6383af8f36f48b4c5d7025094550612eca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
@@ -30,12 +31,12 @@ module ForestAdminDatasourceActiveRecord
|
|
30
31
|
end
|
31
32
|
|
32
33
|
def create(_caller, data)
|
33
|
-
Utils::ActiveRecordSerializer.new(@model.create(data)).to_hash
|
34
|
+
Utils::ActiveRecordSerializer.new(@model.create(data)).to_hash(ProjectionFactory.all(self))
|
34
35
|
end
|
35
36
|
|
36
37
|
def update(_caller, filter, data)
|
37
38
|
entity = Utils::Query.new(self, nil, filter).build.first
|
38
|
-
entity
|
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(
|
@@ -63,49 +68,112 @@ module ForestAdminDatasourceActiveRecord
|
|
63
68
|
end
|
64
69
|
end
|
65
70
|
|
71
|
+
def association_primary_key?(association)
|
72
|
+
!association.association_primary_key.empty?
|
73
|
+
rescue StandardError
|
74
|
+
association.polymorphic?
|
75
|
+
end
|
76
|
+
|
66
77
|
def fetch_associations
|
67
|
-
associations(@model).each do |association|
|
78
|
+
associations(@model, support_polymorphic_relations: @support_polymorphic_relations).each do |association|
|
68
79
|
case association.macro
|
69
80
|
when :has_one
|
70
|
-
|
71
|
-
association.
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
81
|
+
if association_primary_key?(association)
|
82
|
+
if association.through_reflection?
|
83
|
+
add_field(
|
84
|
+
association.name.to_s,
|
85
|
+
ForestAdminDatasourceToolkit::Schema::Relations::ManyToManySchema.new(
|
86
|
+
foreign_collection: format_model_name(association.klass.name),
|
87
|
+
origin_key: association.through_reflection.foreign_key,
|
88
|
+
origin_key_target: association.through_reflection.join_foreign_key,
|
89
|
+
foreign_key: association.join_foreign_key,
|
90
|
+
foreign_key_target: association.association_primary_key,
|
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
|
103
|
+
)
|
104
|
+
)
|
105
|
+
else
|
106
|
+
add_field(
|
107
|
+
association.name.to_s,
|
108
|
+
ForestAdminDatasourceToolkit::Schema::Relations::OneToOneSchema.new(
|
109
|
+
foreign_collection: format_model_name(association.klass.name),
|
110
|
+
origin_key: association.foreign_key,
|
111
|
+
origin_key_target: association.association_primary_key
|
112
|
+
)
|
113
|
+
)
|
114
|
+
end
|
115
|
+
end
|
78
116
|
when :belongs_to
|
79
|
-
|
80
|
-
association
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
117
|
+
if association_primary_key?(association)
|
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
|
+
)
|
128
|
+
)
|
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
|
141
|
+
end
|
87
142
|
when :has_many
|
88
|
-
if association
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
143
|
+
if association_primary_key?(association)
|
144
|
+
if association.through_reflection?
|
145
|
+
add_field(
|
146
|
+
association.name.to_s,
|
147
|
+
ForestAdminDatasourceToolkit::Schema::Relations::ManyToManySchema.new(
|
148
|
+
foreign_collection: format_model_name(association.klass.name),
|
149
|
+
origin_key: association.through_reflection.foreign_key,
|
150
|
+
origin_key_target: association.through_reflection.join_foreign_key,
|
151
|
+
foreign_key: association.join_foreign_key,
|
152
|
+
foreign_key_target: association.association_primary_key,
|
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
|
165
|
+
)
|
98
166
|
)
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
167
|
+
else
|
168
|
+
add_field(
|
169
|
+
association.name.to_s,
|
170
|
+
ForestAdminDatasourceToolkit::Schema::Relations::OneToManySchema.new(
|
171
|
+
foreign_collection: format_model_name(association.klass.name),
|
172
|
+
origin_key: association.foreign_key,
|
173
|
+
origin_key_target: association.association_primary_key
|
174
|
+
)
|
107
175
|
)
|
108
|
-
|
176
|
+
end
|
109
177
|
end
|
110
178
|
end
|
111
179
|
end
|
@@ -2,9 +2,12 @@ require 'active_record'
|
|
2
2
|
|
3
3
|
module ForestAdminDatasourceActiveRecord
|
4
4
|
class Datasource < ForestAdminDatasourceToolkit::Datasource
|
5
|
-
|
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,15 +18,26 @@ 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(
|
21
|
+
add_collection(
|
22
|
+
Collection.new(self, model, support_polymorphic_relations: @support_polymorphic_relations)
|
23
|
+
)
|
19
24
|
end
|
20
25
|
end
|
21
26
|
|
27
|
+
def primary_key?(model)
|
28
|
+
!model.primary_key.empty?
|
29
|
+
rescue StandardError
|
30
|
+
false
|
31
|
+
end
|
32
|
+
|
22
33
|
def fetch_model(model)
|
23
34
|
if model.name.start_with?('HABTM_')
|
24
35
|
build_habtm(model)
|
25
36
|
else
|
26
|
-
@models << model unless model.abstract_class? ||
|
37
|
+
@models << model unless model.abstract_class? ||
|
38
|
+
@models.include?(model) ||
|
39
|
+
!model.table_exists? ||
|
40
|
+
!primary_key?(model)
|
27
41
|
end
|
28
42
|
end
|
29
43
|
|
@@ -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
|
-
|
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
|
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
|
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.
|
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-
|
12
|
+
date: 2024-08-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|