2011-12-31 74 views
1

我的目標是有可能通過用戶名和姓氏以及通過錄入年和學期搜索文檔。 文件只與聲明有關,以便文件與一個聲明連接一個聲明和聲明可以很好地連接到一個或一個文件。Yii框架 - 通過相同的「通過」表的兩個關係

聲明與OutgoingStudent和Recrutation有關。

所以當查詢文件我想通過聲明表查詢OutgoingStudent和Recrutations。

我在文檔中的關係碼:

return array(
         'declaration' => array(self::BELONGS_TO, 'Declaration', 'DeclarationID'), 
      'outgoingStudentUserIdUser' => array(self::HAS_ONE, 'OutgoingStudent', 'OutgoingStudent_User_idUser','through'=>'declaration',), 
       'Recrutation' => array(self::HAS_ONE, 'Recrutation', 'Recrutation_RecrutationID','through'=>'declaration'), 
       ); 

現在當搜索()函數,我要打一個查詢 - >與

'declaration','outgoingStudentUserIdUser' and 'Recrutation': 

       $criteria->with = array('declaration','Recrutation','outgoingStudentUserIdUser'); 

我得到這個錯誤:

CDbCommand nie zdołał wykonać instrukcji SQL: SQLSTATE[42000] [1066] Not unique table/alias: 'declaration'. The SQL statement executed was: SELECT COUNT(DISTINCT t . DeclarationID) FROM Documents t LEFT OUTER JOIN Declarations declaration ON (t . DeclarationID = declaration . idDeclarations) LEFT OUTER JOIN Recrutation Recrutation ON (declaration . Recrutation_RecrutationID = Recrutation . RecrutationID) LEFT OUTER JOIN Declarations declaration ON (t . DeclarationID = declaration . idDeclarations) LEFT OUTER JOIN OutgoingStudent outgoingStudentUserIdUser ON (declaration . OutgoingStudent_User_idUser = outgoingStudentUserIdUser . User_idUser)

僅使用$criteria->with = array('declaration','Recrutation')$criteria->with = array('declaration','outgoingStudentUserIdUser')只有在使用b OTH。

所以可能它應該以其他方式完成,但怎麼做?

回答

2

我有很多事情要告訴你!在這裏他們是:

我發現你的關係函數聲明很雜亂,我不確定它是否正在做你想做的事情(如果它工作的話)。這裏有我的建議重新申報:

首先,'outgoingStudentUserIdUser'看起來像一個關係的可怕的名字。最後,這個關係將會針對outgoingStudentUser的實例,而不僅僅是'id'。所以讓我把它命名爲outgoingStudentUser。現在,這是我的代碼:

'outgoingStudentUser' => array(self::HAS_ONE, 'OutgoingStudent', array('idDocuments'=>'idOutgoingStudent'),'through'=>'declaration',), 

其中「idDocuments」是文檔模式的主鍵,idOutgoingStudent是OutgoingStudent模型的主鍵。

第二個關係可以以非常相似的方式進行修正:

'Recrutation' => array(self::HAS_ONE, 'Recrutation', array('idDocuments'=>'idRecrutation'),'through'=>'declaration'), 

其中「idDocuments」是文檔模式的主鍵,idRecrutation是Recrutation模型的主鍵。

你可以發現,這是正確的聲明在這裏:http://www.yiiframework.com/doc/guide/1.1/en/database.arr#through-on-self

但是這還不是全部。我有更多要告訴你!你用你的代碼做什麼是毫無意義的。 'with'用於強制加載相關對象。在下面的代碼:

$criteria->with = array('declaration','Recrutation','outgoingStudentUserIdUser'); 

你只是規定在$標準,當你在數據庫檢索使用此$標準文件的實例,它也將獲取由作爲通過關係聯繫到該實例的模型參數設置爲'with'。這是急切的加載。它用於減少對數據庫的查詢次數。就像是說:「去數據庫並拿到我這個文檔的實例,但是一旦你到達那裏,就爲所有與這個對象相關的其他表格的實例帶來一次。」

嗯,這就是你所聲明的,但肯定這不是你想要做的。我如何知道?因爲該聲明在search()函數中是無用的。正如你在這裏看到的:http://www.yiiframework.com/doc/api/1.1/CDbCriteria/#with-detail,'with'只在某些函數中有用,而search()不是其中的一個。在搜索內部(),急切的加載是毫無意義的,毫無意義和無用的。

所以我看到自己被迫問你你想做什麼?你說:「我的目標是有可能通過用戶名和姓氏以及通過錄入年和學期來搜索文檔」,但是,「通過用戶名和...搜索文檔」是什麼意思?你想要這樣的東西:$ user-> documents,返回與$ user相關的所有文檔?我希望你能更具體一些,但也許在另一個更具針對性的問題上。

+0

感謝您的意見!我試圖實現的目標是在CGridView中顯示文檔(例如:show(在CGridView中)顯示屬於recrutation id 1且由用戶創建的所有文檔的Recrutations數據和Outgoing Students數據(姓名和姓名)約翰·史密斯)。在搜索()中使用「with」的想法不是我的 - 我在這裏找到它:http://www.yiiframework.com/wiki/281/searching-and-sorting-by-related-model-in-cgridview/ – Pax0r 2012-01-03 20:02:24

+0

原來如此!是的,這是我的錯。現在,你是否嘗試了我的建議?它有用嗎? – 2012-01-03 21:56:00

+0

我已經手寫了一個SQL,但仍然使用了一些一般的技巧,所以我接受你的答案 – Pax0r 2012-01-09 23:07:56

0

你也可以試試這個:

return array(
      'declaration' => array(self::BELONGS_TO, 'Declaration', 'DeclarationID'), 
      'outgoingStudentUserIdUser' => array(self::HAS_ONE, 'OutgoingStudent', 'OutgoingStudent_User_idUser','through'=>'declaration',), 
      'Recrutation' => array(self::HAS_ONE, 'Recrutation', '', 'on'=>'declaration.id=Recrutation.Recrutation_RecrutationID'), 
);