55namespace Tempest \Database ;
66
77use Attribute ;
8+ use Tempest \Database \Builder \ModelInspector ;
89use Tempest \Database \QueryStatements \FieldStatement ;
910use Tempest \Database \QueryStatements \JoinStatement ;
1011use Tempest \Reflection \PropertyReflector ;
@@ -16,13 +17,9 @@ final class HasMany implements Relation
1617{
1718 public PropertyReflector $ property ;
1819
19- public string $ fieldName {
20- get => $ this ->property ->getName () . '. ' . $ this ->localPropertyName ;
21- }
22-
2320 public function __construct (
24- public ?string $ relationJoin = null ,
2521 public ?string $ ownerJoin = null ,
22+ public ?string $ relationJoin = null ,
2623 ) {}
2724
2825 public function getSelectFields (): ImmutableArray
@@ -47,37 +44,63 @@ public function idField(): string
4744
4845 public function getJoinStatement (): JoinStatement
4946 {
50- $ relationModel = model ($ this ->property ->getIterableType ()->asClass ());
51- $ ownerModel = model ($ this ->property ->getClass ());
47+ $ ownerModel = model ($ this ->property ->getIterableType ()->asClass ());
48+ $ relationModel = model ($ this ->property ->getClass ());
5249
53- // chapters.book_id
54- $ relationJoin = $ this ->relationJoin ;
50+ $ ownerJoin = $ this -> getOwnerJoin ( $ ownerModel , $ relationModel );
51+ $ relationJoin = $ this ->getRelationJoin ( $ relationModel ) ;
5552
56- if (! $ relationJoin ) {
57- $ relationJoin = sprintf (
58- ' %s.%s ' ,
59- $ relationModel -> getTableName () ,
60- str ( $ ownerModel -> getTableName ())-> singularizeLastWord () . ' _ ' . $ ownerModel -> getPrimaryKey () ,
61- );
62- }
53+ return new JoinStatement ( sprintf (
54+ ' LEFT JOIN %s ON %s = %s ' ,
55+ $ ownerModel -> getTableName () ,
56+ $ ownerJoin ,
57+ $ relationJoin ,
58+ ) );
59+ }
6360
64- // books.id
61+ private function getOwnerJoin (ModelInspector $ ownerModel , ModelInspector $ relationModel ): string
62+ {
6563 $ ownerJoin = $ this ->ownerJoin ;
6664
67- if (! $ ownerJoin ) {
65+ if ($ ownerJoin && ! strpos ( $ ownerJoin, ' . ' ) ) {
6866 $ ownerJoin = sprintf (
6967 '%s.%s ' ,
7068 $ ownerModel ->getTableName (),
71- $ ownerModel -> getPrimaryKey () ,
69+ $ ownerJoin ,
7270 );
7371 }
7472
75- // LEFT JOIN chapters ON chapters.book_id = books.id
76- return new JoinStatement (sprintf (
77- 'LEFT JOIN %s ON %s = %s ' ,
73+ if ($ ownerJoin ) {
74+ return $ ownerJoin ;
75+ }
76+
77+ return sprintf (
78+ '%s.%s ' ,
79+ $ ownerModel ->getTableName (),
80+ str ($ relationModel ->getTableName ())->singularizeLastWord () . '_ ' . $ relationModel ->getPrimaryKey (),
81+ );
82+ }
83+
84+ private function getRelationJoin (ModelInspector $ relationModel ): string
85+ {
86+ $ relationJoin = $ this ->relationJoin ;
87+
88+ if ($ relationJoin && ! strpos ($ relationJoin , '. ' )) {
89+ $ relationJoin = sprintf (
90+ '%s.%s ' ,
91+ $ relationModel ->getTableName (),
92+ $ relationJoin ,
93+ );
94+ }
95+
96+ if ($ relationJoin ) {
97+ return $ relationJoin ;
98+ }
99+
100+ return sprintf (
101+ '%s.%s ' ,
78102 $ relationModel ->getTableName (),
79- $ relationJoin ,
80- $ ownerJoin ,
81- ));
103+ $ relationModel ->getPrimaryKey (),
104+ );
82105 }
83106}
0 commit comments