2

我用 MongoDB 作为数据库创建了一个小型 Symfony2 网站(使用 Symfony PR11)。我可以创建一个使用普通文档的表单,但是如何使用带有嵌入式文档的文档?

以下是文件:

/**
 * @mongodb:Document(collection="location")
 */
class Location
{
    /**
     * @mongodb:Id
     */
    protected $id;

    /**
     * @mongodb:String
     */
    protected $locationName;

    /**
     * @mongodb:EmbedMany(targetDocument="LocationTerminal")
     */
    protected $terminals = array();

    // Setter

    public function setTerminals(LocationTerminal $terminal)
    {
        array_push($this->terminals, $terminal);
    }

    public function setLocationName($locationName)
    {
        $this->locationName = $locationName;
    }


    // Getter

    public function getId()
    {
        return $this->$id;
    }

    public function getLocationName()
    {
        return $this->locationName;
    }

    public function getTerminals()
    {
        return $this->terminals;
    }

}

嵌入式文档:

/**
 * @mongodb:EmbeddedDocument
 */
class LocationTerminal
{
    /**
     * @mongodb:String
     */
    protected $terminalName;

    /**
     * @mongodb:Int
     */
    protected $since;

    /**
     * @mongodb:Int
     */
    protected $to;

    // Setter

    public function setTerminalName($terminalName)
    {
        $this->terminalName = $terminalName;
    }

    public function setSince($since)
    {
        $this->since = $since;
    }

    public function setTo($to)
    {
        $this->to = $to;
    }

    // Getter

    public function getTerminalName()
    {
        return $this->terminalName;
    }

    public function getSince()
    {
        return $this->since;
    }

    public function getTo()
    {
        return $this->to;
    }

}

如您所见$terminals,拥有一个EmbedMany-Document 这是表格:

class LocationForm extends Form
{
    public function configure()
    {
        $this->add(new TextField('locationName', array('max_length' => 255, 'required' => true)));
    }

    public function addTerminals($dm)
    {
        $this->add(new ChoiceField('terminals.terminalName', array('choices' => $dm)));
        $this->add(new DateField('terminals.since', array('required' => true)));
        $this->add(new DateField('terminals.to', array('required' => false)));
    }
}

使用的控制器如下所示:

class LocationController extends Controller
{
    protected $location;
    protected $locationTerminal;

    protected function getDm()
    {
        return $this->get('doctrine.odm.mongodb.document_manager');
    }

    protected function getLocation($name = null)
    {
        if ($name != null)
        {
            $dm = $this->getDm();
            $this->location = $dm->getRepository('RalfBundle:Location')->findOneBy(array('locationName' => $name));
            if (! $this->location)
            {
                $this->location = new Location();
                $this->locationTerminal = new LocationTerminal();
                $this->location->setLocation($name);
                $this->location->setTerminals($this->locationTerminal);
            }
        }
        else
        {
            $this->location = new Location();
            $this->locationTerminal = new LocationTerminal();
            $this->location->setTerminals($this->locationTerminal);
            $this->locationTerminal->setSince(0);
            $this->locationTerminal->setTerminalName("");
            $this->locationTerminal->setTo(0);
        }
    }


protected function getForm()
{
    $form = LocationForm::create($this->get('form.context'), 'location');
    $dm = $this->getDm();
    $form->addTerminals($dm->getRepository('RalfBundle:Terminal')->findAll()->toArray());
    return $form;
}


//... some Actions

    public function createAction()
    {
        $this->getLocation();
        $form = $this->getForm();

        $form->bind($this->get('request'), $this->location);

        if ($form->isValid())
        {
            $dm = $this->getDm();
            $dm->persist($this->location);
            $dm->flush();
            return $this->redirect($this->generateUrl('Location'));
        }
        return $this->render('RalfBundle:Ralf:location_create.html.twig', array('form' => $form));
    }

我可以看到,locationName接收表单中输入的值,但EmbedMany-Arrayterminals仍然是空的。我做错了什么?

感谢您的帮助:D

更新:

好的,找到了解决方案。

在里面应该是这样public function addTerminals($dm)的:LocationForm

public function addTerminals($dm)
{
    $this->add(new ChoiceField('terminals.0.terminalName', array('choices' => $dm)));
    $this->add(new DateField('terminals.0.since', array('required' => true, 'type'=> 'timestamp')));
    $this->add(new DateField('terminals.0.to', array('required' => false, 'type' => 'timestamp')));
}
  1. 'type' => 'timestamp'是必要的,因为DateField会创建一个DateTime-Object,但文档需要一个Intfor timestamp
  2. -array 中的字段terminals可以通过普通的点表示法访问。
4

2 回答 2

0

Symfony 2 实际上为您提供了一个处理表单中嵌入文档的工具:它被称为“集合字段类型”,它使您能够在父表单中嵌入其他表单类型(来自其他嵌入文档)。

它可以配置为允许/禁止添加/删除嵌入式文档,实际上非常强大。

于 2013-08-14T10:10:19.343 回答
0

好的,找到了解决方案。

在里面应该是这样public function addTerminals($dm)的:LocationForm

public function addTerminals($dm)
{
    $this->add(new ChoiceField('terminals.0.terminalName', array('choices' => $dm)));
    $this->add(new DateField('terminals.0.since', array('required' => true, 'type'=> 'timestamp')));
    $this->add(new DateField('terminals.0.to', array('required' => false, 'type' => 'timestamp')));
}
  1. 'type' => 'timestamp'是必要的,因为DateField会创建一个DateTime-Object,但文档需要一个Intfor timestamp
  2. -array 中的字段terminals可以通过普通的点表示法访问。
于 2012-08-18T08:08:22.337 回答