Php Laravel doctrine2与额外列的多对多关系
因此,当涉及到一个项目的多对多关系时,我开始与Doctrine2作斗争,该关系有一个额外的列 我有以下表格: 轮廓 身份证件 额外数据 技巧 身份证件 名称 profile_拥有_技能 个人资料 技能id 数量 现在我在后面添加了level列,并注意到发生了一些问题,当然,无论何时尝试创建关系,我现在都缺少level。 我的问题是,有了下面的代码,我将如何将其添加到我的教义中 我的控制器:Php Laravel doctrine2与额外列的多对多关系,php,laravel,doctrine-orm,many-to-many,entity-relationship,Php,Laravel,Doctrine Orm,Many To Many,Entity Relationship,因此,当涉及到一个项目的多对多关系时,我开始与Doctrine2作斗争,该关系有一个额外的列 我有以下表格: 轮廓 身份证件 额外数据 技巧 身份证件 名称 profile_拥有_技能 个人资料 技能id 数量 现在我在后面添加了level列,并注意到发生了一些问题,当然,无论何时尝试创建关系,我现在都缺少level。 我的问题是,有了下面的代码,我将如何将其添加到我的教义中 我的控制器: public function store(Request $request) { $time =
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实体如下所示:
/**
* @ORM\Entity
* @ORM\Table(name="profile_has_skill")
*
*/
class ProfileHasSkill
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(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);
}
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();
我在profile实体中的addSkill方法如下:
/**
* @ORM\Entity
* @ORM\Table(name="profile_has_skill")
*
*/
class ProfileHasSkill
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(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);
}
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();
但每当我尝试运行它时,它都会给我以下错误
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
现在我知道了消除这个错误的一种方法是在数据库中设置一个默认值,但我更愿意找出为什么它没有提高我的技能水平,我也通过了?多对多关系的问题是,除了两个表中的两个主键之外的任何其他列都被视为透视列,在将实体附加到此类关系时,您希望使用attach方法,该方法接受ID数组作为第一个参数,并使用具有透视列的数组,请考虑以下因素
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]);
}
希望这能澄清一些事情,即使是以雄辩为例;对于上述代码。根据我的解决方案,通过阅读另一个经过的问题,该原则不支持多对多关系中的额外列。因此,您应该使用关系作为它自己的实体。我自己的解决方案是改变我希望它与法拉盛一起运行的方式 在我的控制器中,我更改了代码,如下所示:
/**
* @ORM\Entity
* @ORM\Table(name="profile_has_skill")
*
*/
class ProfileHasSkill
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(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);
}
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;
}
在我的ProfileHasSkill实体中:
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();
}
我试过了,但遗憾的是doctrine2没有attach方法,问题是doctrine2是一个要求,因为在大型数据库上速度更快,因此我不能使用雄辩的:,add方法也是一个doctrine方法,它会自动填充profile\u has\u skills表,但它缺少level参数,这很奇怪,因为我在控制器中添加了级别,或者至少我认为soI刚刚偶然发现了这意味着你的个人资料\u has\u skills实体将不能有额外的字段,在这种情况下,这是级别,我错了吗?啊,真糟糕!不过,我想我必须在条令中添加我自己的功能才能实现这一点。没错,我认为这对条令来说是一个很大的负面影响,但是,祝你好运:我找到了一个有效的解决方案,如果你感兴趣的话,你可以在上面阅读。