Class: ForestAdminDatasourceToolkit::Utils::Collection
- Inherits:
-
Object
- Object
- ForestAdminDatasourceToolkit::Utils::Collection
- Includes:
- Components::Query, Exceptions, Schema, Schema::Relations
- Defined in:
- lib/forest_admin_datasource_toolkit/utils/collection.rb
Class Method Summary collapse
- .aggregate_relation(collection, primary_key_values, relation_name, caller, foreign_filter, aggregation, limit = nil) ⇒ Object
- .get_field_schema(collection, field_name) ⇒ Object
- .get_inverse_relation(collection, relation_name) ⇒ Object
- .get_through_origin(collection, relation_name) ⇒ Object
- .get_through_target(collection, relation_name) ⇒ Object
- .get_value(collection, caller, primary_key_values, field) ⇒ Object
- .list_relation(collection, primary_key_values, relation_name, caller, foreign_filter, projection) ⇒ Object
- .many_to_many_inverse?(field, relation_field) ⇒ Boolean
- .many_to_one_inverse?(field, relation_field) ⇒ Boolean
- .other_inverse?(field, relation_field) ⇒ Boolean
Class Method Details
.aggregate_relation(collection, primary_key_values, relation_name, caller, foreign_filter, aggregation, limit = nil) ⇒ Object
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/forest_admin_datasource_toolkit/utils/collection.rb', line 159 def self.aggregate_relation(collection, primary_key_values, relation_name, caller, foreign_filter, aggregation, limit = nil) relation = collection.schema[:fields][relation_name] foreign_collection = collection.datasource.get_collection(relation.foreign_collection) if relation.is_a?(ManyToManySchema) && foreign_filter.nestable? foreign_relation = get_through_target(collection, relation_name) if foreign_relation through_collection = collection.datasource.get_collection(relation.through_collection) return through_collection.aggregate( caller, FilterFactory.make_through_filter(collection, primary_key_values, relation_name, caller, foreign_filter), aggregation, limit ) end end foreign_collection.aggregate( caller, FilterFactory.make_foreign_filter(collection, primary_key_values, relation_name, caller, foreign_filter), aggregation, limit ) end |
.get_field_schema(collection, field_name) ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/forest_admin_datasource_toolkit/utils/collection.rb', line 59 def self.get_field_schema(collection, field_name) fields = collection.schema[:fields] unless field_name.include?(':') raise ForestException, "Column not found #{collection.name}.#{field_name}" unless fields.key?(field_name) return fields[field_name] end association_name = field_name.split(':')[0] relation_schema = fields[association_name] raise ForestException, "Relation not found #{collection.name}.#{association_name}" unless relation_schema if relation_schema.type != 'ManyToOne' && relation_schema.type != 'OneToOne' raise ForestException, "Unexpected field type #{relation_schema.type}: #{collection.name}.#{association_name}" end get_field_schema( collection.datasource.get_collection(relation_schema.foreign_collection), field_name.split(':')[1..].join(':') ) end |
.get_inverse_relation(collection, relation_name) ⇒ Object
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/forest_admin_datasource_toolkit/utils/collection.rb', line 9 def self.get_inverse_relation(collection, relation_name) relation_field = collection.schema[:fields][relation_name] foreign_collection = collection.datasource.get_collection(relation_field.foreign_collection) polymorphic_relations = %w[PolymorphicOneToOne PolymorphicOneToMany] inverse = foreign_collection.schema[:fields].select do |_name, field| if polymorphic_relations.include?(relation_field.type) field.is_a?(PolymorphicManyToOneSchema) && field.foreign_key_type_field == relation_field.origin_type_field && field.foreign_key == relation_field.origin_key && field.foreign_collections.include?(collection.name) else field.is_a?(RelationSchema) && field.foreign_collection == collection.name && ( (field.is_a?(ManyToManySchema) && relation_field.is_a?(ManyToManySchema) && many_to_many_inverse?(field, relation_field)) || (field.is_a?(ManyToOneSchema) && (relation_field.is_a?(OneToOneSchema) || relation_field.is_a?(OneToManySchema)) && many_to_one_inverse?(field, relation_field)) || ((field.is_a?(OneToOneSchema) || field.is_a?(OneToManySchema)) && relation_field.is_a?(ManyToOneSchema) && other_inverse?(field, relation_field)) ) end end.keys.first inverse || nil end |
.get_through_origin(collection, relation_name) ⇒ Object
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/forest_admin_datasource_toolkit/utils/collection.rb', line 116 def self.get_through_origin(collection, relation_name) relation = collection.schema[:fields][relation_name] raise ForestException, 'Relation must be many to many' unless relation.is_a?(ManyToManySchema) through_collection = collection.datasource.get_collection(relation.through_collection) through_collection.schema[:fields].select do |field_name, field| if field.is_a?(ManyToOneSchema) && field.foreign_collection == collection.name && field.foreign_key == relation.origin_key && field.foreign_key_target == relation.origin_key_target return field_name end end nil end |
.get_through_target(collection, relation_name) ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/forest_admin_datasource_toolkit/utils/collection.rb', line 99 def self.get_through_target(collection, relation_name) relation = collection.schema[:fields][relation_name] raise ForestException, 'Relation must be many to many' unless relation.is_a?(ManyToManySchema) through_collection = collection.datasource.get_collection(relation.through_collection) through_collection.schema[:fields].select do |field_name, field| if field.is_a?(ManyToOneSchema) && field.foreign_collection == relation.foreign_collection && field.foreign_key == relation.foreign_key && field.foreign_key_target == relation.foreign_key_target return field_name end end nil end |
.get_value(collection, caller, primary_key_values, field) ⇒ Object
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/forest_admin_datasource_toolkit/utils/collection.rb', line 81 def self.get_value(collection, caller, primary_key_values, field) if primary_key_values.is_a? Array index = Schema.primary_keys(collection).index(field) return primary_key_values[index] if index elsif Schema.primary_keys(collection).include?(field) return primary_key_values[field] end records = collection.list( caller, ForestAdminDatasourceToolkit::Components::Query::Filter.new(condition_tree: ConditionTree::ConditionTreeFactory.match_ids(collection, [primary_key_values])), Projection.new([field]) ) records.first&.[](field) end |
.list_relation(collection, primary_key_values, relation_name, caller, foreign_filter, projection) ⇒ Object
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/forest_admin_datasource_toolkit/utils/collection.rb', line 133 def self.list_relation(collection, primary_key_values, relation_name, caller, foreign_filter, projection) relation = collection.schema[:fields][relation_name] foreign_collection = collection.datasource.get_collection(relation.foreign_collection) if relation.is_a?(ManyToManySchema) && foreign_filter.nestable? foreign_relation = get_through_target(collection, relation_name) if foreign_relation through_collection = collection.datasource.get_collection(relation.through_collection) records = through_collection.list( caller, FilterFactory.make_through_filter(collection, primary_key_values, relation_name, caller, foreign_filter), projection.nest(prefix: foreign_relation) ) return records.map { |r| r[foreign_relation] } end end foreign_collection.list( caller, FilterFactory.make_foreign_filter(collection, primary_key_values, relation_name, caller, foreign_filter), projection ) end |
.many_to_many_inverse?(field, relation_field) ⇒ Boolean
38 39 40 41 42 43 44 |
# File 'lib/forest_admin_datasource_toolkit/utils/collection.rb', line 38 def self.many_to_many_inverse?(field, relation_field) field.is_a?(ManyToManySchema) && relation_field.is_a?(ManyToManySchema) && field.origin_key == relation_field.foreign_key && field.through_collection == relation_field.through_collection && field.foreign_key == relation_field.origin_key end |
.many_to_one_inverse?(field, relation_field) ⇒ Boolean
46 47 48 49 50 51 |
# File 'lib/forest_admin_datasource_toolkit/utils/collection.rb', line 46 def self.many_to_one_inverse?(field, relation_field) field.is_a?(ManyToOneSchema) && (relation_field.is_a?(OneToManySchema) || relation_field.is_a?(OneToOneSchema)) && field.foreign_key == relation_field.origin_key end |
.other_inverse?(field, relation_field) ⇒ Boolean
53 54 55 56 57 |
# File 'lib/forest_admin_datasource_toolkit/utils/collection.rb', line 53 def self.other_inverse?(field, relation_field) (field.is_a?(OneToManySchema) || field.is_a?(OneToOneSchema)) && relation_field.is_a?(ManyToOneSchema) && field.origin_key == relation_field.foreign_key end |