根据this tutorial,我正在尝试将Service
表单的集合嵌入到Tag
表单中。 Service
和Tag
个实体具有多对多关系。
表单正确呈现。但是当我提交表格时,我得到了
无法确定属性“tagList”的访问类型
错误。我不明白为什么新的Service
对象没有通过调用addTag()
方法添加到public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title', TextType::class, array(
'label' => 'Title'
))
;
$builder->add('tagList', CollectionType::class, array(
'entry_type' => TagType::class,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false
)));
}
类。
的ServiceType
{
....
/**
* @ORM\ManyToMany(targetEntity="Tag", mappedBy="serviceList",cascade={"persist"})
*/
private $tagList;
/**
* @return ArrayCollection
*/
public function getTagList()
{
return $this->tagList;
}
/**
* @param Tag $tag
* @return Service
*/
public function addTag(Tag $tag)
{
if ($this->tagList->contains($tag) == false) {
$this->tagList->add($tag);
$tag->addService($this);
}
}
/**
* @param Tag $tag
* @return Service
*/
public function removeTag(Tag $tag)
{
if ($this->tagList->contains($tag)) {
$this->tagList->removeElement($tag);
$tag->removeService($this);
}
return $this;
}
}
服务类
{
/**
* @ORM\ManyToMany(targetEntity="Service", inversedBy="tagList")
* @ORM\JoinTable(name="tags_services")
*/
private $serviceList;
/**
* @param Service $service
* @return Tag
*/
public function addService(Service $service)
{
if ($this->serviceList->contains($service) == false) {
$this->serviceList->add($service);
$service->addTag($this);
}
return $this;
}
/**
* @param Service $service
* @return Tag
*/
public function removeService(Service $service)
{
if ($this->serviceList->contains($service)) {
$this->serviceList->removeElement($service);
$service->removeTag($this);
}
return $this;
}
}
标记类
public function newAction(Request $request)
{
$service = new Service();
$form = $this->createForm('AppBundle\Form\ServiceType', $service);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($service);
$em->flush();
return $this->redirectToRoute('service_show', array('id' => $service->getId()));
}
return $this->render('AppBundle:Service:new.html.twig', array(
'service' => $service,
'form' => $form->createView(),
));
}
的ServiceController
String ast_a = "";
String ast_b = "";
String ast_c = "";
String ast_d = "";
String ast_e = "";
int a = Integer.parseInt(request.getParameter("strong-dissatisfy"));
int b = Integer.parseInt(request.getParameter("dissatisfy"));
int c = Integer.parseInt(request.getParameter("neutral"));
int d = Integer.parseInt(request.getParameter("satisfy"));
int e = Integer.parseInt(request.getParameter("strong-satisfy"));
答案 0 :(得分:4)
您能否尝试通过此网址实施代码?
首先,请尝试更改映射/反面,并从$service->addTag($this);
方法中删除Tag::addService
。
答案 1 :(得分:2)
也许问题是Symfony无法访问该属性?
如果你看一下抛出异常的位置(PropertyAccessor类中的writeProperty方法),它会说它可以被抛出:
如果财产不存在或不公开。
在你提到的教程中,它有属性$ tags和方法addTag。我只是在这里猜测,但也许会有一个惯例,它试图调用一个方法名add($singularForm)
,这对你来说是失败的,因为属性是tagList
而方法是{ {1}}。
我不是100%肯定,但您可以通过在Symfony方法中设置一个停止点来尝试调试,以了解它被抛出的原因。
答案 2 :(得分:2)
简短版:
我遇到了这个问题并通过为受影响的属性添加一个setter来解决它:
无法确定属性“tagList”的访问类型
public function setTagList(Array $tagList)
{
$this->tagList = $tagList;
}
长版:
错误消息表明Symfony正在尝试修改对象的状态,但由于其类的设置方式无法弄清楚如何实际进行更改。
Taking a look at Symfony's internals,我们可以看到Symfony为您提供了5次机会,可以从上到下按顺序选择最佳的:
setProperty()
的setter方法,带有一个参数:这是Symfony检查的第一件事,也是实现这一目标的最明确的方法。据我所知,这是最好的做法:
class Entity {
protected $tagList;
//...
public function getTagList()
{
return $this->tagList;
}
//...
}
重要的是要意识到Symfony也会访问此方法,以便获取对象的状态。由于这些方法调用不包含参数,因此此方法中的参数必须是可选的。
class Entity {
protected $tagList;
//...
public function tagList($tags = null)
{
if($reps){
$this->tagList = $tags;
} else {
return $this->tagList;
}
}
//...
}
受影响的财产被宣布为公共:
class Entity {
public $tagList;
//... other properties here
}
__set
魔法:
这将影响所有属性,而不仅仅是您想要的属性。
class Entity {
public $tagList;
//...
public function __set($name, $value){
$this->$name = $value;
}
//...
}
__call
魔法(在某些情况下):我无法确认这一点,但内部代码建议在PropertyAccessor构建时启用magic
时可以这样做。
只需使用上述策略之一。
答案 3 :(得分:1)
也许您忘记了__construct()
Service类和Tag类来初始化$ tagList和$ serviceList?
$this->tagList = new ArrayCollection();
$this->serviceList = new ArrayCollection();
答案 4 :(得分:1)
这似乎是构造函数的错误。试试这个:
public function __construct()
{
$this-> tagList = new \Doctrine\Common\Collections\ArrayCollection();
}
答案 5 :(得分:1)
这是一个很长的镜头,但看着你的注释,我认为问题可能与你的manyToMany关系有关。尝试更改拥有方和反方(交换关系),除非您特别需要从两端更新(在这种情况下,我认为唯一的解决方案是手动添加对象或使用oneToMany关系)。
忽略仅对关联的反面进行的更改。 确保更新双向关联的两侧(或在 至少是拥有方,从学说的角度来看)
这是一个与我以前遇到过的学说相关的问题,请参阅: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/unitofwork-associations.html
答案 6 :(得分:0)
基于Symfony 3.3.10
我实际上遇到过很多次这个问题,最后一旦我发现这个问题来自哪里,根据您给实体属性的名称,可能会发生加法器和<您的收藏属性的strong> remover 并不完全符合您的预期。
示例:您的实体属性名称为“foo”,您可能希望将加法器称为“addFoo”并将其移除“removeFoo”,但突然之后“无法确定属性的访问类型” 出现。
因此,您开始担心在代码中搜索w / e问题,而只需在Symfony核心文件中查看此文件:
<强>供应商/ symfony的/ symfony的/ SRC / Symfony的/组件/ PropertyAccess / PropertyAccessor.php 强>
在此文件中,有一个名为 findAdderAndRemover 的方法。 使用您的调试器去那里,您最终会发现symfony会为您的加法器/移除器搜索奇怪的名称,它们实际上可能以“um”或“on”或“us”结尾,具体取决于语言(人类语言)你曾经用它们命名。因为我是意大利人,所以这种情况经常发生。
注意这一点,因为修复可能就像更改实体中用于添加/删除方法的名称一样简单,以使它们与Symfony核心所寻找的匹配。
当我使用 bin / console doctrine:generate:entities 为我自动创建方法时,这种情况发生在我身上
答案 7 :(得分:0)
如果您正在使用symfony,并使用EntityRepository而不是CollectionType,请确保在表单构建中使用df['month']=df.month
,否则输入将针对一个实体而不是多个实体,因此它将调用{ {1}}而不是使用方法'multiple' => true,
和setTagList
。