Laravel Doctrine2与额外的专栏许多关系



因此,当涉及一个关系的多对多关系时,我开始与Doctrine2挣扎,该项目的关系有一个额外的列。

我有以下表:

  • 个人资料
    • id
    • 额外数据
  • 技能

    • id
    • 名称
  • profile_has_skills

    • profile_id
    • skill_id
    • 级别

现在,我稍后添加了级别的列,并注意到发生了一些问题,当然,每当我尝试创建关系时,我现在都缺少级别。我的问题是,有了以下代码,我将如何在我的学说中添加它?

我的控制器:

public function store(Request $request)
{
    $time = new DateTime();
    $this->validate($request, [
        'name' => 'required',
        'lastname' => 'required',
        'gender' => 'required',
        'profile_skills' => 'required'
    ]);
    $this->em->getConnection()->beginTransaction();
    try {
        $profile = new Profile(
            $request->input('company_id'),
            $request->input('name'),
            $request->input('lastname'),
            $request->input('gender'),
            new DateTime(),
            $time,
            $time
        );
        $company = $this->em->getRepository(Company::class)->find($request->input('company_id'));
        $profile->addCompany($company);
        foreach($request->input('profile_skills') as $skill => $level) {
            $skill = $this->em->getRepository(Skill::class)->find($skill);
            $skill->level = $level;
            $profile->addSkill($skill);
        }
        $this->em->persist($profile);
        $this->em->flush();
        $this->em->getConnection()->commit();
    } catch (OptimisticLockException $e) {
        $this->em->getConnection()->rollBack();
        throw $e;
    }
    return redirect(route('profiles.index'));
}

我的profilehasskill实体看起来如下:

/**
 * @ORMEntity
 * @ORMTable(name="profile_has_skill")
 *
 */
class ProfileHasSkill
{
/**
 * @ORMId
 * @ORMGeneratedValue
 * @ORMColumn(type="integer")
 */
protected $id;
/**
 * @Column(type="integer", name="profile_id")
 */
protected $profile_id;

/**
 * @Column(type="integer", name="skill_id")
 */
protected $skill_id;
/**
 * @Column(type="integer", name="level")
 */
protected $level;
/**
 * @param $profile_id
 * @param $skill_id
 * @param $level
 */
public function __construct($profile_id, $skill_id, $level = 0)
{
    $this->profile_id = $profile_id;
    $this->skill_id = $skill_id;
    $this->level = $level;
}

和我在配置文件实体内部的添加方法如下:

public function addSkill(Skill $skill)
{
    if ($this->skills->contains($skill)) {
        return;
    }
    return $this->skills->add($skill);
}

但是,每当我尝试运行它时,它都会给我以下错误

An exception occurred while executing 
'INSERT INTO profile_has_skill (profile_id, skill_id) VALUES (?, ?)' 
with params [3, 2]: SQLSTATE[HY000]: General error: 1364 Field 'level' 
doesn't have a default value

现在,我知道摆脱此错误的一种方法是在数据库中设置一个默认值,但是我宁愿找出为什么它也没有掌握我也通过的技能水平?

<</p>

根据我的解决方案,通过阅读@nicola Havric通过的另一个问题,如下所示,该学说不支持多对多的关系中的额外列。因此,您应该将关系用作自己的实体。我自己的解决方案是更改我希望它与Flushing运行的方式。

在控制器中,我更改了代码如下:

try {
    $profile = new Profile(
        $request->input('company_id'),
        $request->input('name'),
        $request->input('lastname'),
        $request->input('gender'),
        new DateTime(),
        $time,
        $time
    );
    $company = $this->em->getRepository(Company::class)->find($request->input('company_id'));
    $profile->addCompany($company);
    //Flush the user, so I can grab it's profile ID
    $this->em->persist($profile);
    $this->em->flush();
    foreach($request->input('profile_skills') as $skill => $level) {
        $skill = $this->em->getRepository(Skill::class)->find($skill);
        $skill->level = $level;
        $profile->addSkill($skill);
    }

    $this->em->getConnection()->commit();

在我的个人资料实体函数中:

public function addSkill(Skill $skill)
{
    //I left this check since it only checks if the relation is set already. If so, it will skip it.
    if ($this->skills->contains($skill)) {
        return;
    }
    //Since this function gets called inside a loop, I can call the entity to add a new "relation" to the table.
    (new ProfileHasSkill($this->getId(), $skill, $skill->level))->addSkill($this->getId(), $skill, $skill->level);
    return true;
}

在我的个人资料中心实体中:

 public function addSkill($profileId, $skill)
{
    //Creating a new ProfileHasSkill inside the table.
    $profileSkill = new ProfileHasSkill(
        $profileId,
        $skill->getId(),
        $skill->level
    );
    /*Since I do a roll-back inside my controller in case something goes wrong.
       I decided to add the flush here. 
       As far no additional checks where needed in my case 
       since I require a Profile instance and a Skill instance inside the Profile entity.*/
    EntityManager::persist($profileSkill);
    EntityManager::flush();
}

具有多一关系的事物是,两张表的两个主要键以外的其他列都被视为 pivot 列,将实体附加到这样您需要使用方法附加的关系,该接受ID数组作为第一个参数和带有 pivot 列的数组,请考虑以下内容。

public function addSkill(Skill $skill)
{
    if ($this->skills->contains($skill)) {
        return;
    }
    //Dunno what this method does
    return $this->skills->add($skill);
    //But this is the correct way of adding a skill
    $this->skills->attach($skill->id, ['level' => $skill->level]);
}

希望这可以澄清一些事情,即使以雄辩为例。这是上述代码的手册链接。

相关内容

  • 没有找到相关文章

最新更新