2

MongoDBをDBとして使用して小さなSymfony2-Webサイト(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;
    }

}

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

}

ご覧のとおり、 -Document$terminalsが保持されています。フォームは次のとおりです。EmbedMany

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フォームに入力された値を受け取ることがわかりましたが、-ArrayEmbedManyterminalsまだ空です。私は何を間違えましたか?

助けてくれてありがとう: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'が必要です。'causeは-ObjectDateFieldを作成しますDateTimeが、ドキュメントはIntforを期待していましたtimestamp
  2. -arrayのフィールドには、terminals通常のドット表記でアクセスできます。
4

2 に答える 2

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'が必要です。'causeは-ObjectDateFieldを作成しますDateTimeが、ドキュメントはIntforを期待していましたtimestamp
  2. -arrayのフィールドには、terminals通常のドット表記でアクセスできます。
于 2012-08-18T08:08:22.337 に答える
0

Symfony 2は、実際にフォームに埋め込まれたドキュメントを処理するツールを提供します。これは「コレクションフィールドタイプ」と呼ばれ、他のフォームタイプ(他の埋め込みドキュメントから)を親フォームに埋め込むことができます。

埋め込まれたドキュメントの追加/削除を許可/禁止するように構成でき、実際には非常に強力です。

于 2013-08-14T10:10:19.343 に答える