Doctrine ODM DocumentManager not found – založení projektu s MongoDB a Doctrine ODM
- d3tr1tus
- Člen | 52
Ahoj zakládám si nový projekt, kde chci využívat MongoDB a Doctrine ODM. Samotné Mongo mi funguje bez problému. Podle návodu na Doctrine dokumentaci jsem udělal vše co se tam píše. A do bootstrap.php jsem přidal kód:
use Doctrine\MongoDB\Connection;
use Doctrine\ODM\MongoDB\Configuration;
use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver;
if ( ! file_exists($file = __DIR__ . '/../vendor/autoload.php')) {
throw new RuntimeException('Install dependencies to run this script.');
}
$loader = require_once $file;
$loader->add('Documents', __DIR__);
$connection = new Connection();
$config = new Configuration();
$config->setProxyDir(__DIR__ . '/Proxies');
$config->setProxyNamespace('Proxies');
$config->setHydratorDir(__DIR__ . '/Hydrators');
$config->setHydratorNamespace('Hydrators');
$config->setDefaultDB('zupa');
$config->setMetadataDriverImpl(AnnotationDriver::create(__DIR__ . '/Documents'));
AnnotationDriver::registerAnnotationClasses();
$dm = DocumentManager::create($connection, $config);
ale když chci založit například nového uživatele v modelu vyhodí to exception
Service '24_App_Model_UserModel' (type of App\Model\UserModel): Service of type Doctrine\ODM\MongoDB\DocumentManager needed by $odm in App\Model\BaseModel::__construct() not found. Did you register it in configuration file?
v BaseModelu jsem dal do konstruktoru
public function __construct(DocumentManager $odm)
{
$this->odm = $odm;
}
protože jinak to psalo undefined variable $odm.
mohl by jste mi někdo poradit jak by to mohlo fungovat prosím?
- Mysteria
- Člen | 797
Takhle ti to fungovat nebude, protože je sice pěkný, že si v bootstrapu vytvoříš instanci DocumentManageru, ale nikde jej neregistruješ jako službu do Nette DI kontejneru, takže o ní Nette neví a tudíž ti jej nemůže předat do tvého modelu.
Řešení jsou prakticky dvě. Buď zkusíš najít nějakou existující extension pro Nette, která to udělá za tebe jako existuje například pro ORM. Pokud žádná neexistuje, tak je to horší a musíš si ji zkonfigurovat sám.
Pro inspiraci takhle si registruju EntityManager pro ORM sám bez použití extension, pro ODM to bude hodně podobné:
services:
-
create: Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain
setup:
- addDriver(Doctrine\ORM\Mapping\Driver\AnnotationDriver(Doctrine\Common\Annotations\AnnotationReader(), [%appDir%/Model/Entity]), 'Model\Entity')
-
create: Doctrine\ORM\Tools\Setup::createAnnotationMetadataConfiguration([%appDir%/Model/Entity], FALSE, '%tempDir%/cache/Doctrine2.ORM', Doctrine\Common\Cache\FilesystemCache('%tempDir%/cache/Doctrine2.ORM'))
setup:
- setAutoGenerateProxyClasses(Doctrine\Common\Proxy\AbstractProxyFactory::AUTOGENERATE_FILE_NOT_EXISTS)
- setMetadataDriverImpl(@Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain)
- setNamingStrategy(Doctrine\ORM\Mapping\UnderscoreNamingStrategy())
- setProxyNamespace(Proxy)
- Doctrine\ORM\EntityManager::create([
driver: pdo_mysql
host: project-mariadb
user: root
password: root
dbname: project
charset: utf8
])
- d3tr1tus
- Člen | 52
Díky za radu @Mysteria. Extension jsem našel pouze tuhle Document manager extension , ale píše mi to, že není stabilní. Tak se to snažím nastavit ručně podle návodu co si mi poslal a mám dotaz. V bootstrapu.php jsem si to zaregistroval, jak jsem psal výše. V configu jsem si zaregistroval
- Doctrine\ODM\MongoDB\DocumentManager::create()
ale píše mi to error
You must configure a hydrator directory. See docs for details.
Jak můžu předat tohle z bootstrapu
AnnotationDriver::registerAnnotationClasses();
$dm = DocumentManager::create($connection, $config);
do configu?
- Mysteria
- Člen | 797
Mohlo by to být zhruba takhle (nestestoval jsem):
services:
- Doctrine\MongoDB\Connection
-
create: Doctrine\ODM\MongoDB\Configuration
setup:
- setMetadataDriverImpl(Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver::create([%appDir%/Model/Documents]))
- setProxyDir('%tempDir%/cache/Doctrine2.ODM')
- setProxyNamespace(Proxy)
- setHydratorDir('%tempDir%/cache/Doctrine2.ODM')
- setHydratorNamespace(Hydrator)
- Doctrine\ODM\MongoDB\DocumentManager::create
Editoval Mysteria (10. 8. 2018 18:39)
- d3tr1tus
- Člen | 52
@Mysteria moc ti děkuju za pomoc s tímhle už mi to neházelo žádnou chybu a vracelo to záznamy uživatele jako kdyby fungoval persist, ale když jsem na to zavolal flush tak to záznam neuložilo. Nakonec jsem to vyřešil celý následovně.
Vytvořil jsem si BaseModel, který bude rozšiřovat všechny podmodely a vložil do konstruktoru
$connection = new Connection();
$config = new Configuration();
$config->setProxyDir(__DIR__ . '/../temp/Proxies');
$config->setProxyNamespace('Proxies');
$config->setHydratorDir(__DIR__ . '/../temp/Hydrators');
$config->setHydratorNamespace('Hydrators');
$config->setDefaultDB('name_database');
$config->setMetadataDriverImpl(AnnotationDriver::create(__DIR__ . '/Documents'));
$this->dm = DocumentManager::create($connection, $config);
teď už mi stačí v podmodelu zavolat jen nějaký dokument například User a nadefinovat mu všechny parametry a nakonec zavolat
$this->dm->persist($user);
$this->dm->flush();
a všechno běží jako na drátkách :D
Díky moc za trpělivost :)