关系不渴望加载

时间:2018-08-14 14:10:36

标签: laravel laravel-5 eloquent

上下文

我有3次迁移:

成员表:

<?php   

class CreateMembersTable extends Migration
{    
    public function up()
    {
        Schema::create('members', function (Blueprint $table) {

             $table->increments('id');
             $table->string('name')->unique();
             $table->timestamps();
        });
    }    
}

成员链接类型表:

<?php

class CreateMemberLinkTypesTable extends Migration
{
    public function up()
    {
        Schema::create('member_link_types', function (Blueprint $table) {

            $table->string('name', 50)->primary()->unique();
            $table->string('category', 50)->index();
            $table->string('description', 50)->unique();
            $table->string('description_on_male', 50);
            $table->string('description_on_female', 50);
            $table->string('reverse_link', 50);
    });

    Artisan::call('db:seed', [
        '--class' => MemberLinkTypeSeeder::class
    ]);

    Schema::table('member_link_types', function ($table) {

        $table->foreign('reverse_link')->references('name')->on('member_link_types');
    });
}

并且,成员链接表:

<?php

class CreateMemberLinksTable extends Migration
{

    public function up()
    {
        Schema::create('member_links', function (Blueprint $table) {

            $table->increments('id');
            $table->string('member_link_type', 50)->index();
            $table->integer('from_member_id')->unsigned()->index();
            $table->integer('to_member_id')->unsigned()->index();
            $table->timestamps();
            $table->foreign('member_link_type')->references('name')->on('member_link_types');
            $table->foreign('from_member_id')->references('id')->on('members');
            $table->foreign('to_member_id')->references('id')->on('members');
        });
    }

}

seed member_link_types 表之后,它看起来像这样:

name   | category | description | description_on_male| description_on_female| reverse_link |
-------|----------|-------------|--------------------|----------------------|--------------|
child  | family   | Child       | son                | daughter             | parent |
parent | family   | Parent      | dad                | mon                  | child |
sibling| family   | Sibling     | brother            | sister               | sibling |
spouse | family   | Spouse      | husband            | wife                 | spouse |

因此,我在“成员链接类”模型中定义了关系:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class MemberLink extends Model
{        

    protected $with = [
        'from', 'to', 'type'
    ];

    public function from()
    {
        return $this->belongsTo('App\Member', 'from_member_id');
    }

    public function to()
    {
        return $this->belongsTo('App\Member', 'to_member_id');
    }

    public function type()
    {
        return $this->belongsTo('App\MemberLinkType', 'member_link_type', 'name');
    }    

}

问题

鉴于我有这样的表“ member_links”:

| id | member_link_type | from_member_id | to_member_id |
|----|------------------|----------------|--------------|
| 1  | parent           |      1         |       2      | 

当我加载模型时

$link = MemberLink::find(1)

我明白了:

App\MemberLink {#3012
     id: 1,
     member_link_type: "parent",
     from_member_id: 1,
     to_member_id: 2,
     from: App\Member {#3024
       id: 1,
       name: "Micaela Beltrão",       
     },
     to: App\Member {#3022
       id: 2,
       name: "Ian Fernandes",       
     },
     type: null,
   }

即,已成功加载 to from 属性,但 type 关系没有成功(空)。

但是,如果我尝试直接从对象建立关系,则会得到不同的结果:

$link = MemberLink::find(1);
$link->belongsTo('App\MemberLinkType', 'member_link_type', 'name')->get()

为此:

=> Illuminate\Database\Eloquent\Collection {#3013
 all: [
   App\MemberLinkType {#3032
     name: "parent",
     category: "family",
     description: "Parent",
     description_on_male: "dad",
     description_on_female: "mom",
     reverse_link: "child",
   },
 ],

}

如何获取要加载的类型关系?

我正在使用Laravel 5.6。

更新1

在AarónGutiérrez建议之后,我添加了一个代理键(整数列)作为member_link_types表的键,并进行了必要的更改之后:

$link = MemberLink::find(1)
=> App\MemberLink {#3019
     id: 1,
     member_link_types_id: 1,
     from_member_id: 11,
     to_member_id: 12,
     created_at: "2018-08-14 14:28:46",
     updated_at: "2018-08-14 14:28:46",
     from: App\Member {#3031
       id: 11,
       name: "Simon Ferminiano",           
       created_at: "2018-08-14 14:24:49",
       updated_at: "2018-08-14 14:24:49",
     },
     to: App\Member {#3029
       id: 12,
       name: "Luciano Leon",

       created_at: "2018-08-14 14:24:52",
       updated_at: "2018-08-14 14:24:52",
     },
     type: App\MemberLinkType {#3030
       id: 1,
       name: "parent",
       category: "family",
       description: "Parent",
       description_on_male: "dad",
       description_on_female: "mom",
       reverse_link: 2,
     },

所以,我认为将文本字段用作表的主键时会受到一些限制吗?

3 个答案:

答案 0 :(得分:0)

在特定情况下,使用VARCHAR数据类型字段作为外键的目的是什么?

  

VARCHAR用于任何KEY的问题是它们可以保持   白色空间。空白由任何非屏幕可读的内容组成   字符,例如空格标签,回车符等。使用VARCHAR作为   当您开始寻找原因时,一把钥匙会使您的生活变得困难   表返回的记录末尾没有多余的空格   键。

如此处所述:VARCHAR as foreign key/primary key in database good or bad?

所以,这可能是个问题。

答案 1 :(得分:0)

默认情况下,只有模型关键点会出现在枢轴对象上。如果数据透视表包含额外的属性,则在定义关系时必须指定它们:

return $this->belongsTo('App\MemberLinkType')->withPivot('member_link_type');

来自https://laravel.com/docs/5.6/eloquent-relationships

编辑对不起,您尝试过吗?

$link->belongsTo('App\MemberLinkType', 'member_link_type', 'name')->with('type');

答案 2 :(得分:0)

我能够解决。 在$incrementing模型中,必须将false属性设置为MemberLinkType

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class MemberLinkType extends Model
{
    public $timestamps = false;    
    public $incrementing = false;    
    protected $primaryKey = 'name';    

}

那之后,我得到了想要的东西:

$link = MemberLink::find(1)
=> App\MemberLink {#3071
     id: 1,
     member_link_type: "parent",
     from_member_id: 11,
     to_member_id: 12,
     created_at: "2018-08-14 15:03:22",
     updated_at: "2018-08-14 15:03:22",
     from: App\Member {#3065
       id: 11,
       name: "Gabriela Espinoza",           
     },
     to: App\Member {#3067
       id: 12,
       name: "Felipe Assunção",           
     },
     type: App\MemberLinkType {#3066
       name: "parent",
       category: "family",
       description: "Parent",
       description_on_male: "dad",
       description_on_female: "mom",
       reverse_link: "child",
     },
   }