【问题标题】:how to add an existing_model as many-to-many relation to a dummy_mode in laravel如何将现有模型作为多对多关系添加到 laravel 中的 dummy_mode
【发布时间】:2021-04-24 03:53:26
【问题描述】:

我正在尝试在 laravel 中制作一个测试用例。

  1. 我有一个 fake User 模型(数据库中存在该模型),并使用 faker->make 创建它,

  2. 和一个存在于数据库中的真实 角色模型,

这两个有一个多对多的关系

在我的测试用例中,我将像这里一样关联它们:

public function testAccess()
{
        $user = factory(\App\User::class)->make();
        $supervisionControllerRole = \App\Role::where('name', 'supervision_controller')->first();
        $user->roles->add($supervisionControllerRole);
}

因为我不想在数据库中保存关系,所以我使用add() 而不是attach()

$user->roles()->attach($supervisionControllerRole->id);
//resulting database modification.

问题

我的问题是,当我试图从模型中获取关系时, 没问题。

var_dump($user->roles->first());

但是当我试图获得关系在模型中时,它确实有效。

喜欢我的User 模特:

public function hasRole($roleName)
{
    $role_id = Cache::tags(['role_id'])->remember($roleName, 24*3600, function () use ($roleName) {
        return \App\Role::where('name', $roleName)->first()->id;
    });
    return $this->roles()->where('role_id', $role_id)->exists();
}

它将returns false 并尝试$this->roles->count() 结果0 从模型内部。

我的定义

User 模型中:

public function roles()
{
    return $this->belongsToMany("App\Role", "role_user")->whereNull("deleted_at")->using("App\RoleUser");
}

用户工厂:

$factory->define(User::class, function (Faker $faker) {
    return [
        'id' => $faker->randomNumber(),
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'email_verified_at' => now(),
        'password' => Str::random(80), // password
        'remember_token' => Str::random(10),
    ];
});

【问题讨论】:

    标签: php laravel unit-testing eloquent eloquent-relationship


    【解决方案1】:

    每当你调用带括号的关系时,例如

    return $this->roles()->where('role_id', $role_id)->exists();
                       ^^
    

    您正在访问一个Builder 查询实例,该实例将从数据库返回信息。但是您的数据不在数据库中,所以当它在那里查找时当然不会找到任何东西。

    当您直接add() 关系(与attach() 相比)时,您将插入Collection 实例,您知道这不会影响数据库。此信息仅保存在模型上并存储在内存中。因此,当你这样做时

    var_dump($user->roles->first());
    

    它会找到信息,因为它已经在内存中。 (您也应该可以在这里调用$user->roles->count() 并获得一个非零值。)

    而且由于它是模型与直接属性的关系,我什至认为如果您要使用模型 save() ,它不会更新数据库。

    如果不存储在数据库中,可以使用contains方法执行第一步:

    return $this->roles->contains($role_id);
    

    【讨论】:

    • 感谢您的回复。但是如果我不想用return $this->roles->contains($role_id); 修改我的模型并编写测试用例,你有什么建议吗?看来,我必须创建一个 test_db 但是,我正在寻找另一个解决方案。
    • 您没有针对单独的测试数据库进行测试?这就解释了为什么您不想将模型保存到数据库中。
    猜你喜欢
    • 2021-10-25
    • 1970-01-01
    • 1970-01-01
    • 2021-01-27
    • 1970-01-01
    • 1970-01-01
    • 2016-12-10
    • 2019-03-03
    • 2017-07-01
    相关资源
    最近更新 更多