<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                [TOC] # 模型關系 ## 模型之間的關系 有四種類型的關系:一對一,一對多,多對一和多對多。關系可以是單向的或雙向的,并且每個可以是簡單的(一對一模型)或更復雜的(模型的組合)。模型管理器管理這些關系的外鍵約束,這些關系的定義有助于參照完整性以及相關記錄對模型的輕松快速訪問。通過關系的實現,可以很容易地以統一的方式從每個記錄中訪問相關模型中的數據。 ### 單向關系 單向關系是彼此相關而不是相反生成的關系。 ### 雙向關系 兩個模型和每個模型中的雙向關系構建關系定義了另一個的反向關系。 ### 定義關系 在Phalcon中,必須在模型的 `initialize()` 方法中定義關系。方法`belongsTo()`,`hasOne()`,`hasMany()` 和 `hasManyToMany()` 定義從當前模型到另一個模型中的字段的一個或多個字段之間的關系。這些方法中的每一個都需要3個參數:本地字段,引用模型,引用字段。 | 方法 | 描述 | | ------------- | -------------------------- | | hasMany | 定義1對n的關系 | | hasOne | 定義1對1的關系 | | belongsTo | 定義n對1的關系 | | hasManyToMany | 定義n對n的關系 | 以下模式顯示了3個表,其關系將作為關系的示例提供給我們: ```sql CREATE TABLE robots ( id int(10) unsigned NOT NULL AUTO_INCREMENT, name varchar(70) NOT NULL, type varchar(32) NOT NULL, year int(11) NOT NULL, PRIMARY KEY (id) ); CREATE TABLE robots_parts ( id int(10) unsigned NOT NULL AUTO_INCREMENT, robots_id int(10) NOT NULL, parts_id int(10) NOT NULL, created_at DATE NOT NULL, PRIMARY KEY (id), KEY robots_id (robots_id), KEY parts_id (parts_id) ); CREATE TABLE parts ( id int(10) unsigned NOT NULL AUTO_INCREMENT, name varchar(70) NOT NULL, PRIMARY KEY (id) ); ``` * The model `Robots` has many `RobotsParts`. * The model `Parts` has many `RobotsParts`. * The model `RobotsParts` belongs to both `Robots` and `Parts` models as a many-to-one relation. * The model `Robots` has a relation many-to-many to `Parts` through `RobotsParts`. 利用EER圖以更好地理解關系: ![](https://docs.phalconphp.com/images/content/models-relationships-eer-1.png) 具有關系的模型可以實現如下: ```php <?php namespace Store\Toys; use Phalcon\Mvc\Model; class Robots extends Model { public $id; public $name; public function initialize() { $this->hasMany( 'id', 'RobotsParts', 'robots_id' ); } } ``` ```php <?php use Phalcon\Mvc\Model; class Parts extends Model { public $id; public $name; public function initialize() { $this->hasMany( 'id', 'RobotsParts', 'parts_id' ); } } ``` ```php <?php use Phalcon\Mvc\Model; class RobotsParts extends Model { public $id; public $robots_id; public $parts_id; public function initialize() { $this->belongsTo( 'robots_id', 'Store\Toys\Robots', 'id' ); $this->belongsTo( 'parts_id', 'Parts', 'id' ); } } ``` 第一個參數表示關系中使用的本地模型的字段;第二個表示引用模型的名稱,第三個表示引用模型中的字段名稱。您還可以使用數組來定義關系中的多個字段。 許多關系需要3個模型并定義關系中涉及的屬性: ```php <?php namespace Store\Toys; use Phalcon\Mvc\Model; class Robots extends Model { public $id; public $name; public function initialize() { $this->hasManyToMany( 'id', 'RobotsParts', 'robots_id', 'parts_id', 'Parts', 'id' ); } } ``` ### 利用關系 在明確定義模型之間的關系時,很容易找到特定記錄的相關記錄。 ```php <?php use Store\Toys\Robots; $robot = Robots::findFirst(2); foreach ($robot->robotsParts as $robotPart) { echo $robotPart->parts->name, "\n"; } ``` Phalcon使用魔術方法`__set`/`__get`/`__call` 來使用關系存儲或檢索相關數據。 通過訪問與關系同名的屬性將檢索其所有相關記錄。 ```php <?php use Store\Toys\Robots; $robot = Robots::findFirst(); // All the related records in RobotsParts $robotsParts = $robot->robotsParts; ``` 此外,你可以使用魔術getter: ```php <?php use Store\Toys\Robots; $robot = Robots::findFirst(); // All the related records in RobotsParts $robotsParts = $robot->getRobotsParts(); // Passing parameters $robotsParts = $robot->getRobotsParts( [ 'limit' => 5, ] ); ``` 如果被調用的方法有一個`get` 前綴,`Phalcon\Mvc\Model` 將返回一個`findFirst()`/`find()`結果。以下示例將使用魔術方法和不使用魔術方法檢索相關結果進行比較: ```php <?php use Store\Toys\Robots; $robot = Robots::findFirst(2); // Robots model has a 1-n (hasMany) // relationship to RobotsParts then $robotsParts = $robot->robotsParts; // Only parts that match conditions $robotsParts = $robot->getRobotsParts( [ 'created_at = :date:', 'bind' => [ 'date' => '2015-03-15' ] ] ); $robotPart = RobotsParts::findFirst(1); // RobotsParts model has a n-1 (belongsTo) // relationship to RobotsParts then $robot = $robotPart->robots; ``` 手動獲取相關記錄: ```php <?php use Store\Toys\Robots; $robot = Robots::findFirst(2); // Robots model has a 1-n (hasMany) // relationship to RobotsParts, then $robotsParts = RobotsParts::find( [ 'robots_id = :id:', 'bind' => [ 'id' => $robot->id, ] ] ); // Only parts that match conditions $robotsParts = RobotsParts::find( [ 'robots_id = :id: AND created_at = :date:', 'bind' => [ 'id' => $robot->id, 'date' => '2015-03-15', ] ] ); $robotPart = RobotsParts::findFirst(1); // RobotsParts model has a n-1 (belongsTo) // relationship to RobotsParts then $robot = Robots::findFirst( [ 'id = :id:', 'bind' => [ 'id' => $robotPart->robots_id, ] ] ); ``` 前綴`get` 用于 `find()`/`findFirst()` 相關記錄。根據關系類型,它將使用 `find()`或`findFirst()`: | 類型 | 描述 | 隱含方法 | | ---------------- | -------------------------------------------------------------------------------------------------------------------------- | --------------- | | Belongs-To | 直接返回相關記錄的模型實例 | findFirst | | Has-One | 直接返回相關記錄的模型實例 | findFirst | | Has-Many | 返回引用模型的模型實例的集合 | find | | Has-Many-to-Many | 返回引用模型的模型實例的集合,它隱含地與所涉及的模型進行“內部聯接” | (complex query) | 您還可以使用 `count` 前綴返回一個表示相關記錄計數的整數: ```php <?php use Store\Toys\Robots; $robot = Robots::findFirst(2); echo 'The robot has ', $robot->countRobotsParts(), " parts\n"; ``` ### 別名關系 為了更好地解釋別名的工作原理,讓我們檢查以下示例: `robots_similar` 表具有定義哪些機器人與其他機器人相似的功能: ```sql mysql> desc robots_similar; +-------------------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------------+------------------+------+-----+---------+----------------+ | id | int(10) unsigned | NO | PRI | NULL | auto_increment | | robots_id | int(10) unsigned | NO | MUL | NULL | | | similar_robots_id | int(10) unsigned | NO | | NULL | | +-------------------+------------------+------+-----+---------+----------------+ 3 rows in set (0.00 sec) ``` `robots_id` 和`similar_robots_id`都與模型機器人有關: ![](https://docs.phalconphp.com/images/content/models-relationships-eer-1.png) 映射此表及其關系的模型如下: ```php <?php class RobotsSimilar extends Phalcon\Mvc\Model { public function initialize() { $this->belongsTo( 'robots_id', 'Store\Toys\Robots', 'id' ); $this->belongsTo( 'similar_robots_id', 'Store\Toys\Robots', 'id' ); } } ``` 由于兩個關系都指向同一個模型(Robots),因此獲取與關系相關的記錄不能清楚: ```php <?php $robotsSimilar = RobotsSimilar::findFirst(); // Returns the related record based on the column (robots_id) // Also as is a belongsTo it's only returning one record // but the name 'getRobots' seems to imply that return more than one $robot = $robotsSimilar->getRobots(); // but, how to get the related record based on the column (similar_robots_id) // if both relationships have the same name? ``` 別名允許我們重命名這兩個關系來解決這些問題: ```php <?php use Phalcon\Mvc\Model; class RobotsSimilar extends Model { public function initialize() { $this->belongsTo( 'robots_id', 'Store\Toys\Robots', 'id', [ 'alias' => 'Robot', ] ); $this->belongsTo( 'similar_robots_id', 'Store\Toys\Robots', 'id', [ 'alias' => 'SimilarRobot', ] ); } } ``` 通過別名,我們可以輕松獲得相關記錄。您還可以使用`getRelated()`方法使用別名來訪問關系: ```php <?php $robotsSimilar = RobotsSimilar::findFirst(); // Returns the related record based on the column (robots_id) $robot = $robotsSimilar->getRobot(); $robot = $robotsSimilar->robot; $robot = $robotsSimilar->getRelated('Robot'); // Returns the related record based on the column (similar_robots_id) $similarRobot = $robotsSimilar->getSimilarRobot(); $similarRobot = $robotsSimilar->similarRobot; $similarRobot = $robotsSimilar->getRelated('SimilarRobot'); ``` #### Magic Getters vs.明確的方法 大多數具有自動完成功能的IDE和編輯器在使用魔法getter(方法和屬性)時都無法推斷出正確的類型。要解決這個問題,您可以使用類docblock來指定可用的魔術操作,從而幫助IDE生成更好的自動完成: ```php <?php namespace Store\Toys; use Phalcon\Mvc\Model; /** * Model class for the robots table. * @property Simple|RobotsParts[] $robotsParts * @method Simple|RobotsParts[] getRobotsParts($parameters = null) * @method integer countRobotsParts() */ class Robots extends Model { public $id; public $name; public function initialize() { $this->hasMany( 'id', 'RobotsParts', 'robots_id' ); } } ``` ## 條件語句 您還可以根據條件創建關系。根據關系查詢時,條件將自動附加到查詢中: ```php <?php use Phalcon\Mvc\Model; // Companies have invoices issued to them (paid/unpaid) // Invoices model class Invoices extends Model { } // Companies model class Companies extends Model { public function initialize() { // All invoices relationship $this->hasMany( 'id', 'Invoices', 'inv_id', [ 'alias' => 'Invoices' ] ); // Paid invoices relationship $this->hasMany( 'id', 'Invoices', 'inv_id', [ 'alias' => 'InvoicesPaid', 'params' => [ 'conditions' => "inv_status = 'paid'" ] ] ); // Unpaid invoices relationship + bound parameters $this->hasMany( 'id', 'Invoices', 'inv_id', [ 'alias' => 'InvoicesUnpaid', 'params' => [ 'conditions' => "inv_status <> :status:", 'bind' => ['status' => 'unpaid'] ] ] ); } } ``` 此外,在從模型對象訪問關系時,可以使用 `getRelated()` 的第二個參數來進一步過濾或排序關系: ```php <?php // Unpaid Invoices $company = Companies::findFirst( [ 'conditions' => 'id = :id:', 'bind' => ['id' => 1], ] ); $unpaidInvoices = $company->InvoicesUnpaid; $unpaidInvoices = $company->getInvoicesUnpaid(); $unpaidInvoices = $company->getRelated('InvoicesUnpaid'); $unpaidInvoices = $company->getRelated( 'Invoices', ['conditions' => "inv_status = 'paid'"] ); // Also ordered $unpaidInvoices = $company->getRelated( 'Invoices', [ 'conditions' => "inv_status = 'paid'", 'order' => 'inv_created_date ASC', ] ); ``` ## 虛擬外鍵 默認情況下,關系不像數據庫外鍵,也就是說,如果您嘗試在引用的模型中插入/更新值而沒有有效值,Phalcon將不會生成驗證消息。您可以通過在定義關系時添加第四個參數來修改此行為。 可以更改RobotsPart模型以演示此功能: ```php <?php use Phalcon\Mvc\Model; class RobotsParts extends Model { public $id; public $robots_id; public $parts_id; public function initialize() { $this->belongsTo( 'robots_id', 'Store\Toys\Robots', 'id', [ 'foreignKey' => true ] ); $this->belongsTo( 'parts_id', 'Parts', 'id', [ 'foreignKey' => [ 'message' => 'The part_id does not exist on the Parts model' ] ] ); } } ``` 如果更改 `belongsTo()` 關系以充當外鍵,它將驗證在這些字段上插入/更新的值在引用的模型上是否具有有效值。同樣,如果更改了`hasMany()`/`hasOne()` ,它將驗證如果在引用的模型上使用該記錄,則無法刪除記錄。 ```php <?php use Phalcon\Mvc\Model; class Parts extends Model { public function initialize() { $this->hasMany( 'id', 'RobotsParts', 'parts_id', [ 'foreignKey' => [ 'message' => 'The part cannot be deleted because other robots are using it', ] ] ); } } ``` 可以設置虛擬外鍵以允許空值,如下所示: ```php <?php use Phalcon\Mvc\Model; class RobotsParts extends Model { public $id; public $robots_id; public $parts_id; public function initialize() { $this->belongsTo( 'parts_id', 'Parts', 'id', [ 'foreignKey' => [ 'allowNulls' => true, 'message' => 'The part_id does not exist on the Parts model', ] ] ); } } ``` ### 級聯/限制操作 默認情況下充當虛擬外鍵的關系會限制記錄的創建/更新/刪除以維護數據的完整性: ```php <?php namespace Store\Toys; use Phalcon\Mvc\Model; use Phalcon\Mvc\Model\Relation; class Robots extends Model { public $id; public $name; public function initialize() { $this->hasMany( 'id', 'Parts', 'robots_id', [ 'foreignKey' => [ 'action' => Relation::ACTION_CASCADE, ] ] ); } } ``` 如果刪除主記錄(robot),上面的代碼設置為刪除所有引用的記錄(部分)。 ## 存儲相關記錄 Magic屬性可用于存儲記錄及其相關屬性: ```php <?php // Create an artist $artist = new Artists(); $artist->name = 'Shinichi Osawa'; $artist->country = 'Japan'; // Create an album $album = new Albums(); $album->name = 'The One'; $album->artist = $artist; // Assign the artist $album->year = 2008; // Save both records $album->save(); ``` 將記錄及其相關記錄保存在有多個關系中: ```php <?php // Get an existing artist $artist = Artists::findFirst( 'name = 'Shinichi Osawa'' ); // Create an album $album = new Albums(); $album->name = 'The One'; $album->artist = $artist; $songs = []; // Create a first song $songs[0] = new Songs(); $songs[0]->name = 'Star Guitar'; $songs[0]->duration = '5:54'; // Create a second song $songs[1] = new Songs(); $songs[1]->name = 'Last Days'; $songs[1]->duration = '4:29'; // Assign the songs array $album->songs = $songs; // Save the album + its songs $album->save(); ``` 保存album和artist同時隱含地使用事務,因此如果保存相關記錄出現任何問題,父級也不會保存。消息將傳遞回用戶以獲取有關任何錯誤的信息。 注意:無法通過重載以下方法添加相關實體: * `Phalcon\Mvc\Model::beforeSave()` * `Phalcon\Mvc\Model::beforeCreate()` * `Phalcon\Mvc\Model::beforeUpdate()` 您需要重載`Phalcon\Mvc\Model::save()`才能在模型中工作。 ## 對結果集的操作 如果結果集由完整對象組成,則它可以對記錄執行操作: ### 更新相關記錄 不要這樣做: ```php <?php $parts = $robots->getParts(); foreach ($parts as $part) { $part->stock = 100; $part->updated_at = time(); if ($part->update() === false) { $messages = $part->getMessages(); foreach ($messages as $message) { echo $message; } break; } } ``` 你可以這樣做: ```php <?php $robots->getParts()->update( [ 'stock' => 100, 'updated_at' => time(), ] ); ``` `update` 還接受匿名函數來過濾必須更新的記錄: ```php <?php $data = [ 'stock' => 100, 'updated_at' => time(), ]; // Update all the parts except those whose type is basic $robots->getParts()->update( $data, function ($part) { if ($part->type === Part::TYPE_BASIC) { return false; } return true; } ); ``` ### 刪除相關記錄 不要這樣做: ```php <?php $parts = $robots->getParts(); foreach ($parts as $part) { if ($part->delete() === false) { $messages = $part->getMessages(); foreach ($messages as $message) { echo $message; } break; } } ``` 你可以這樣做: ```php <?php $robots->getParts()->delete(); ``` `delete()` 還接受匿名函數來過濾必須刪除的記錄: ```php <?php // Delete only whose stock is greater or equal than zero $robots->getParts()->delete( function ($part) { if ($part->stock < 0) { return false; } return true; } ); ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看