首页 文章

Laravel与多个自定义数据透视表的多对多关系?

提问于
浏览
0

我希望我不会问一个已经回答的问题,但是使用我能想到的所有搜索词我无法解决这个问题:

我有两个表, companiesrespondents

有时,受访者可以 select 一个或多个公司 . 一个公司可以由一个或多个受访者 selected .

其他时候,受访者可以 rate 一个或多个公司 . 一个公司可以由一个或多个受访者 rated .

一个公司的受访者可能是 selectrate . (事实上,所有被调查者都必须选择的公司,但他们并不评价他们选择的所有公司) .

作为进一步的复杂情况,被访者只是一家公司的 employee ,并且也是一家或多家公司的选择和评级 .

我的想法是拥有多个自定义支点:

//relationship between 'companies' and 'respondents' to show who they selected 
selected_companies 

//relationship between 'companies' and 'respondents' to show who they rated 
rated_companies 

//relationship between 'companies' and 'respondents' to show which companies a respondent was nominated by 
nominating_companies

//relationship between 'companies' and 'respondents' to show who a respondent is employed by
employment

我猜最后一个是一个简单的一个,所以我可以在 respondents 表中放一个名为FK employer_id 的自定义 .

除此之外,我对如何实现这一点感到非常困惑 . 我知道自定义中间枢轴模型是一个东西,但我也无法弄清楚如何实现它 .

1 回答

  • 1

    好的,所以这就是我处理这个问题的方法 .

    自定义数据透视表

    在数据透视中,我添加了一个名为 type 的列 . 这就是我的 company_respondent 数据透视表迁移现在的样子:

    Schema::create('company_respondent', function (Blueprint $table) {
            $table->unsignedInteger('company_id');
            $table->unsignedInteger('respondent_id');
            $table->string('type');
    
            $table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade');
            $table->foreign('respondent_id')->references('id')->on('respondents')->onDelete('cascade');
            $table->primary(['company_id','respondent_id','type']);
        });
    

    请注意,对于主键,我使用所有三列 . 这将允许我在同一公司 - 受访者对之间声明不同类型的关系,例如当受访者选择了一家公司时,我可以存储 selected ,当他们对公司进行评级时,我可以将 rated 存储在 type 列中 .

    withPivot

    在我能够做到这一点之前,我需要告诉Laravel在定义关系时期望在 CompanyRespondent 模型中使用 withPivot() 这个新列 . 我需要在关系的两个方面做到这一点:

    //Respondent.php
    
        use App\Company;
    
        public function companies() 
        {
            return $this->belongsToMany(Company::class)->withPivot('type');
        }
    
    
    //Company.php
    
        use App\Respondent;
    
        public function respondents() 
        {
            return $this->belongsToMany(Respondent::class)->withPivot('type');
        }
    

    完成后,我现在可以在保存关系时存储到该列中,并使用它进行过滤 .

    存储:

    $respondent->companies()->attach($companies_selected, ['type'=> 'selected']);
    

    $companies_selected 是单个id或id数组 .

    过滤:

    //returns an array of company names that a respondent with an id of `2` has selected.
    
    $company_names = Respondent::find(2)
                        ->companies()
                        ->wherePivot('type','selected')
                        ->pluck('name')->toArray();
    

    我可以简单地用 selectedratednominated 或我喜欢的任何其他东西来定义两个表之间可能存在的不同类型的关系 .

    我希望这可以帮助其他人,或者我得到更好的方法来做到这一点的反馈 .

相关问题