@@ -45,6 +45,40 @@ module Relation
4545 { 'id' => 203 , 'other_id' => 203 , 'name' => 'Joseph P. Rodriguez' }
4646 ]
4747 end
48+ let ( :comment_records ) do
49+ [
50+ {
51+ 'id' => 301 ,
52+ 'text' => 'Great!' ,
53+ 'commentable_id' => 101 ,
54+ 'commentable_type' => 'passport' ,
55+ 'commentable' => { 'commentable_id' => 101 , 'commentable_type' => 'passport' }
56+ } ,
57+ {
58+ 'id' => 302 ,
59+ 'text' => 'Nice' ,
60+ 'commentable_id' => 201 ,
61+ 'commentable_type' => 'person' ,
62+ 'commentable' => { 'commentable_id' => 201 , 'commentable_type' => 'person' }
63+ }
64+ ]
65+ end
66+ let ( :address_records ) do
67+ [
68+ {
69+ 'id' => 401 ,
70+ 'street' => '123 Main St' ,
71+ 'addressable_id' => 201 ,
72+ 'addressable_type' => 'person'
73+ } ,
74+ {
75+ 'id' => 402 ,
76+ 'street' => '456 Oak Ave' ,
77+ 'addressable_id' => 202 ,
78+ 'addressable_type' => 'person'
79+ }
80+ ]
81+ end
4882
4983 before do
5084 datasource = Datasource . new
@@ -84,13 +118,40 @@ module Relation
84118 aggregation . apply ( passport_records , caller . timezone , limit )
85119 end
86120
121+ collection_address = build_collection (
122+ name : 'address' ,
123+ schema : {
124+ fields : {
125+ 'id' => ColumnSchema . new ( column_type : PrimitiveType ::NUMBER , is_primary_key : true , filter_operators : [ Operators ::EQUAL , Operators ::IN ] ) ,
126+ 'street' => ColumnSchema . new ( column_type : PrimitiveType ::STRING ) ,
127+ 'addressable_id' => ColumnSchema . new ( column_type : PrimitiveType ::NUMBER , filter_operators : [ Operators ::IN ] ) ,
128+ 'addressable_type' => ColumnSchema . new ( column_type : PrimitiveType ::STRING )
129+ }
130+ } ,
131+ datasource : datasource
132+ )
133+
134+ allow ( collection_address ) . to receive ( :list ) do |_caller , filter , projection |
135+ result = ForestAdminDatasourceToolkit ::Utils ::HashHelper . convert_keys ( address_records , :to_s )
136+ result = filter . condition_tree . apply ( result , collection_address , 'Europe/Paris' ) if filter &.condition_tree
137+
138+ projection . apply ( result )
139+ end
140+
87141 collection_person = build_collection (
88142 name : 'person' ,
89143 schema : {
90144 fields : {
91145 'id' => ColumnSchema . new ( column_type : PrimitiveType ::NUMBER , is_primary_key : true , filter_operators : [ Operators ::EQUAL , Operators ::IN ] ) ,
92146 'other_id' => ColumnSchema . new ( column_type : PrimitiveType ::NUMBER , filter_operators : [ Operators ::IN ] ) ,
93- 'name' => ColumnSchema . new ( column_type : PrimitiveType ::STRING , filter_operators : [ Operators ::IN ] )
147+ 'name' => ColumnSchema . new ( column_type : PrimitiveType ::STRING , filter_operators : [ Operators ::IN ] ) ,
148+ 'address' => Relations ::PolymorphicOneToOneSchema . new (
149+ origin_key : 'addressable_id' ,
150+ origin_key_target : 'id' ,
151+ foreign_collection : 'address' ,
152+ origin_type_field : 'addressable_type' ,
153+ origin_type_value : 'person'
154+ )
94155 }
95156 } ,
96157 datasource : datasource
@@ -107,9 +168,37 @@ module Relation
107168 aggregation . apply ( person_records , caller . timezone , limit )
108169 end
109170
171+ collection_comment = build_collection (
172+ name : 'comment' ,
173+ schema : {
174+ fields : {
175+ 'id' => ColumnSchema . new ( column_type : PrimitiveType ::NUMBER , is_primary_key : true , filter_operators : [ Operators ::EQUAL , Operators ::IN ] ) ,
176+ 'text' => ColumnSchema . new ( column_type : PrimitiveType ::STRING ) ,
177+ 'commentable_id' => ColumnSchema . new ( column_type : PrimitiveType ::NUMBER , filter_operators : [ Operators ::IN ] ) ,
178+ 'commentable_type' => ColumnSchema . new ( column_type : PrimitiveType ::STRING ) ,
179+ 'commentable' => Relations ::PolymorphicManyToOneSchema . new (
180+ foreign_key_type_field : 'commentable_type' ,
181+ foreign_key : 'commentable_id' ,
182+ foreign_key_targets : { 'passport' => 'id' , 'person' => 'id' } ,
183+ foreign_collections : %w[ passport person ]
184+ )
185+ }
186+ } ,
187+ datasource : datasource
188+ )
189+
190+ allow ( collection_comment ) . to receive ( :list ) do |_caller , filter , projection |
191+ result = ForestAdminDatasourceToolkit ::Utils ::HashHelper . convert_keys ( comment_records , :to_s )
192+ result = filter . condition_tree . apply ( result , collection_comment , 'Europe/Paris' ) if filter &.condition_tree
193+
194+ projection . apply ( result )
195+ end
196+
110197 datasource . add_collection ( collection_picture )
111198 datasource . add_collection ( collection_passport )
199+ datasource . add_collection ( collection_address )
112200 datasource . add_collection ( collection_person )
201+ datasource . add_collection ( collection_comment )
113202
114203 @datasource_decorator = DatasourceDecorator . new ( datasource , relation_collection_decorator )
115204 end
@@ -606,6 +695,33 @@ module Relation
606695 end
607696 end
608697 end
698+
699+ context 'with polymorphic relations' do
700+ it 'handles PolymorphicManyToOne without error' do
701+ records = @datasource_decorator . get_collection ( 'comment' ) . list (
702+ caller ,
703+ Filter . new ,
704+ Projection . new ( %w[ id text commentable:commentable_id ] )
705+ )
706+
707+ expect ( records ) . to eq ( [
708+ { 'id' => 301 , 'text' => 'Great!' , 'commentable' => { 'commentable_id' => 101 } } ,
709+ { 'id' => 302 , 'text' => 'Nice' , 'commentable' => { 'commentable_id' => 201 } }
710+ ] )
711+ end
712+
713+ it 'handles PolymorphicOneToOne without error' do
714+ records = @datasource_decorator . get_collection ( 'person' ) . list (
715+ caller ,
716+ Filter . new ,
717+ Projection . new ( %w[ id name address:street ] )
718+ )
719+
720+ expect ( records . length ) . to eq ( 3 )
721+ expect ( records . first ) . to have_key ( 'id' )
722+ expect ( records . first ) . to have_key ( 'name' )
723+ end
724+ end
609725 end
610726 end
611727 end
0 commit comments