sfPropelManyToManyが遅すぎる

どうやらsfFinderクラスで全モデルをファイル検索してるのが原因

テーブル数が少ないうちは問題にならないので、結構気づきにくかったりするけど、テーブル数が200とか300になってくると、恐ろしく重くなってくる。

探してみると、やっぱり同じように気になってる人がいて、ここ で取り上げられてる。

で、以下が問題の箇所。

  public static function getRelatedClass($class, $middleClass)
  {
    $column = self::getRelatedColumn($class, $middleClass);
 
    // we must load all map builder classes
    $classes = sfFinder::type('file')->name('*MapBuilder.php')->in(sfLoader::getModelDirs());
    foreach ($classes as $class)
    {
      $class_map_builder = basename($class, '.php');
      $map = new $class_map_builder();
      $map->doBuild();
    }
 
    $tableMap = call_user_func(array($middleClass.'Peer', 'getTableMap'));
 
    return $tableMap->getDatabaseMap()->getTable($column->getRelatedTableName())->getPhpName();
  }
 

いくらなんでも全部読み込むことないでしょ…

で、それがこんな感じで修正されてます

  public static function getRelatedClass($class, $middleClass)
  {
    $column = self::getRelatedColumn($class, $middleClass);
 
    $config_dbmap =
    sfConfig::get('sf_config_cache_dir').'/config_dbMap.php';
    if (is_readable($config_dbmap))
    {
      require($config_dbmap);
    }
    else
    {
      $cache = new sfFileCache(sfConfig::get('sf_config_cache_dir'));
      $cache->setSuffix('');
      $classes =
      sfFinder::type('file')->name('*MapBuilder.php')->in(sfLoader::getModelDirs());
 
      foreach ($classes as $key=>$class)
      {
        $data[] = sprintf("'%s' => '%s',", $key, $class);
      }
 
      $data = sprintf("<?php\n".
                      "// auto-generated by sfPropelManyToMany\n".
                      "// date: %s\n\$classes = array(\n%s\n);\n",
      date('Y/m/d H:i:s'), implode("\n", $data));
 
      $cache->set('config_dbMap.php', '', $data);
    }
 
    foreach ($classes as $class)
    {
      $class_map_builder = basename($class, '.php');
      $map = new $class_map_builder();
      $map->doBuild();
    }
 
    $tableMap = call_user_func(array($middleClass.'Peer', 'getTableMap'));
 
    return
    $tableMap->getDatabaseMap()->getTable($column->getRelatedTableName())->getPhpName();
  }

でも、結局全モデルをビルドしてることには変わりないんで、それならいっそ結合キーになってるカラムを指定してやったほうが早いと思い、sfPoropelFastManyToManyなるクラスをつくり、それをadmin generatorに適用しました。