开发者

EmbedMany in Form

开发者 https://www.devze.com 2023-02-26 13:00 出处:网络
I\'ve created a small Symfony2-Website (with Symfony PR11) with MongoDB as DB. I could create a form, that use a normal document, but how do I use a document with an embeddedDocument?

I've created a small Symfony2-Website (with Symfony PR11) with MongoDB as DB. I could create a form, that use a normal document, but how do I use a document with an embeddedDocument?

here are the documents:

/**
 * @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;
    }

}

The EmbeddedDocument:

/**
 * @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;
    }

}

As you can see $terminals holds an EmbedMany-Document Here's the form:

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)));
    }
}

The used Controller looks like this:

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-&开发者_StackOverflow中文版gt;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));
    }

I could see, that locationName recieve the entered values in the form, but the EmbedMany-Array terminals is still empty. What did I wrong?

Thanks for helping :D

UPDATED:

Ok, found a solution.

in public function addTerminals($dm) in LocationForm it should look like this:

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' is necessary, 'cause DateField will create an DateTime-Object, but the document expected an Int for timestamp.
  2. a field from the terminals-array could be accessed by normal dot-notation.


Ok, found a solution.

in public function addTerminals($dm) in LocationForm it should look like this:

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' is necessary, 'cause DateField will create an DateTime-Object, but the document expected an Int for timestamp.
  2. a field from the terminals-array could be accessed by normal dot-notation.


Symfony 2 actually gives you a tool to handle embedded documents in forms: It's called "collection field type" and it enables you to embed other formtypes (from other embedded documents) in a parent form.

It can be configured to allow/forbid addition/deletion of embedded documents and is actually quite powerful.

0

精彩评论

暂无评论...
验证码 换一张
取 消