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
フォームに入力された値を受け取ることがわかりましたが、-ArrayEmbedMany
はterminals
まだ空です。私は何を間違えましたか?
助けてくれてありがとう: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')));
}
'type' => 'timestamp'
が必要です。'causeは-ObjectDateField
を作成しますDateTime
が、ドキュメントはInt
forを期待していましたtimestamp
。- -arrayのフィールドには、
terminals
通常のドット表記でアクセスできます。