簡體   English   中英

Laravel口才ORM中的多租戶關系

[英]Relationships in multi tenancy in Laravel Eloquent ORM

再次這是對以下問題的跟進問題:

Laravel Eloquent ORM中的多租戶

這次,我對在雄辯模型的多租戶環境中使用關系存在疑問。

給定產品模型:

class Product extends Eloquent {

public function accessories()
{
    return $this->belongsToMany('Accessory', 'product_accessory', 'product_id', 'accessory_id')
                ->withPivot('id')
                ->withTimestamps();
}

有什么簡單的方法可以確保關系方法Accessories()使用正確的數據庫連接? 現在,當我執行這樣的attach方法時:

$product->accessories()->attach($accessory->id, $attributes);

附件方法似乎指向與$ product實體不同的另一個數據庫。 我相信這是因為實例化關系時,附件模型連接不會更改。

如果您看到我對有關模型事件和觀察者的原始問題的回答,這也應該從本質上解決此問題: Laravel Eloquent ORM中的多租戶

所有雄辯的關系方法:附加,關聯等...均觸發相應的模型事件,如此處所述: http : //laravel.com/docs/5.0/eloquent#model-events

如果您設置了模型觀察器以在保存特定模型之前或之后使用操縱模型的連接,則所有關系調用都將自動適當地設置數據庫連接。

希望這可以幫助

-編輯以回應評論

嗨,玉倫

對不起,我誤把您的配件電話聯系了。 (保存關系)

但是,在定義您的關系后,您應該能夠獲得類似的結果。 請參見以下示例:

class ProductModel extends Eloquent {

    protected $table = 'products';

    protected $connection;

    protected $databases = [
        'default' => 'mysql-key1',
        'products' => 'mysql-key2'
    ];

    public function __construct(Connection $connection)
    {
        $this->connection = $connection;
    }

    public function accessories()
    {
        $this->connection->reconnect($this->databases['products']);
        $accessories = $this->hasMany('AccessoriesModel');
        $this->connection->reconnect($this->databases['default']);

        return $accessories;
    }
}

然后,您可以通過創建所有受影響的模型都可以擴展的抽象類來進一步擴展它,例如:

abstract class DatabaseModel extends Eloquent {

     protected $connection;

     protected $databases = [
         'default' => 'mysql-key1',
         'products' => 'mysql-key2'
     ];

     public function __construct(Connection $connection)
     {
         $this->connection = $connection;
     }

    protected function setProductsDatabase()
    {
        $this->connection->reconnect($this->databases['products']);
    }

    protected function resetDatabaseConnection()
    {
        $this->connection->reconnect($this->databases['default']);
    }
}

class ProductModel extends DatabaseModel {

    protected $table = 'products';

    public function accessories()
    {
        $this->setProductsDatabase();
        $accessories = $this->hasMany('AccessoriesModel');
        $this->resetDatabaseConnection();

        return $accessories;
    }
}

這樣,只要您的關系已正確配置,一切都將“自然”地進行,而無需任何其他代碼。

一個更巧妙但更復雜的解決方案是,您可以觸發自己的“檢索”事件,而不是在模型中操作數據庫,然后可以為自定義“檢索”事件向模型觀察器添加事件處理程序-這將是我的喜好,您可以在此處找到有關操作方法的更多信息: http : //laravel.io/forum/05-24-2014-how-could-i-create-custom-model-events?page=1

希望這可以幫助

根據Beevee的回答,我們還可以將Eloquent類擴展為基本模型,以使用基於會話或基於配置的連接,例如

class BaseModel extends Eloquent {

public function __construct(array $attributes = array())
{
    parent::__construct($attributes);

    $this->setConnection(\DB::getDefaultConnection());
}

}

這樣,所有關聯方法將自動實例化以使用連接。

class Product extends BaseModel {

public function accessories()
{
  return $this->belongsToMany('Accessory', 'product_accessory', 'product_id', 'accessory_id')
            ->withPivot('id')
            ->withTimestamps();
}

如果Accessory類也擴展了BaseModel。 這樣,您可以在運行時隨意更改數據庫連接。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM