Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Pomm Bundle Laravel Package

conserto/pomm-bundle

Symfony bundle providing a pomm service to use the Pomm Model Manager with Symfony. Configure one or more PostgreSQL connections via DSNs, enable optional logging, and access Pomm CLI commands (e.g., model generation and database browsing) through bin/console.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup for Daily Use

  1. Install the Bundle:

    composer require conserto/pomm-bundle
    
  2. Configure Database Connections (config/packages/pomm.yaml):

    pomm:
        configuration:
            default:
                dsn: "pgsql://%env(DATABASE_URL)%"
                pomm:default: true
    
    • Use environment variables (.env) for credentials (e.g., DATABASE_URL=postgres://user:pass@127.0.0.1:5432/db).
  3. Generate Models via CLI:

    php bin/console pomm:generate:relation-all -d src/Model -a 'App\Model' default student
    
    • This creates a StudentModel in src/Model/DefaultSchema/ with auto-generated relations.
  4. First Query in a Controller:

    use App\Model\DefaultSchema\StudentModel;
    
    public function listStudents(PommManager $pomm): Response
    {
        $students = $pomm['default']
            ->getModel(StudentModel::class)
            ->findAll();
    
        return $this->render('student/list.html.twig', ['students' => $students]);
    }
    
    • Inject PommManager (auto-registered as a service) to access databases.
  5. Enable Dev Tools (Optional): Add to config/routes/dev/pomm.yaml:

    _pomm:
        resource: "@PommBundle/Resources/config/routing.yml"
        prefix: /_pomm
    
    • Access /_pomm for a database browser and query profiler.

First Use Case: CRUD with JSONB

  1. Define a Model with JSONB:
    // src/Model/DefaultSchema/PostModel.php
    namespace App\Model\DefaultSchema;
    
    use PommProject\ModelManager\Model\Model;
    
    class PostModel extends Model
    {
        protected $table = 'posts';
        protected $jsonbColumns = ['metadata']; // JSONB column
    }
    
  2. Query JSONB Data:
    $posts = $pomm['default']
        ->getModel(PostModel::class)
        ->findWhere('metadata->>\'tags\' @> $*', ['["laravel"]']);
    
  3. Serialize to API Response:
    use Symfony\Component\Serializer\SerializerInterface;
    
    public function getPost(PostModel $post, SerializerInterface $serializer): JsonResponse
    {
        return new JsonResponse($serializer->serialize($post, 'json'));
    }
    

Implementation Patterns

1. Database-Agnostic Service Layer

Pattern: Use tagged services to register models/layers dynamically.

# config/services.yaml
services:
    App\Model\DefaultSchema\StudentModel:
        tags: ['pomm.model', { session: 'default' }]

Workflow:

  • Define models as services with pomm.model tag.
  • Inject PommManager into controllers/services to access any tagged model.
  • Benefit: Avoids hardcoding model paths; models are auto-discovered.

2. Value Resolver for Entity Injection

Pattern: Use Symfony’s Value Resolver to fetch entities from request params.

use Conserto\PommBundle\ValueResolver\EntityValueResolver;

#[Route('/students/{id}')]
public function show(
    #[Entity('default', modelClass: StudentModel::class)]
    StudentModel $student
): Response
{
    return $this->render('student/show.html.twig', ['student' => $student]);
}

Workflow:

  • The resolver maps {id} to StudentModel::find($id).
  • Supports custom model classes via modelClass attribute.
  • Benefit: Clean URLs (e.g., /students/42) without manual find() calls.

3. Multi-Database Transactions

Pattern: Use PommManager to coordinate transactions across databases.

public function transferFunds(
    PommManager $pomm,
    TransactionalInterface $transaction
): void
{
    $transaction->begin($pomm['primary'], $pomm['replica']);

    try {
        $pomm['primary']->getModel(AccountModel::class)->debit($accountId, 100);
        $pomm['replica']->getModel(LogModel::class)->log('Debit', $accountId);
        $transaction->commit();
    } catch (\Exception $e) {
        $transaction->rollback();
    }
}

Workflow:

  • Register a transaction service (e.g., pomm.transactional).
  • Pass PommManager to services needing cross-DB transactions.
  • Benefit: Atomic operations across PostgreSQL instances.

4. CLI-Driven Development

Pattern: Generate models/relations from the schema.

# Generate all relations for a table
php bin/console pomm:generate:relation-all -d src/Model -a 'App\Model' default student

# Generate a single model
php bin/console pomm:generate:model -d src/Model -a 'App\Model' default post

Workflow:

  • Run commands in post-deploy or post-migration hooks.
  • Benefit: Keeps models in sync with the database schema.

5. Custom Poolers for Connection Management

Pattern: Extend connection pooling with custom poolers.

# config/services.yaml
services:
    App\Pooler\CustomPooler:
        tags: ['pomm.pooler']
        arguments:
            - '@pomm.connection_factory'

Workflow:

  • Implement PommProject\Pomm\Connection\PoolerInterface.
  • Tag the service with pomm.pooler.
  • Benefit: Reuse connections efficiently (e.g., for read replicas).

Gotchas and Tips

Pitfalls

  1. DSN Configuration:

    • Gotcha: Forgetting to URL-encode special characters in DATABASE_URL (e.g., @ in passwords).
    • Fix: Use %env(DATABASE_URL)% with Symfony’s .env parser or encode manually:
      dsn: "pgsql://user:%24pass@host:5432/db"  # $ encoded as %24
      
  2. Model Namespace Mismatches:

    • Gotcha: The bundle expects models in src/Model/{DatabaseSchema}/ by default. Custom paths require:
      pomm:
          configuration:
              default:
                  model_namespace: 'App\Models'
      
    • Tip: Use -a 'App\Models' in CLI commands to override.
  3. Symfony 6+ Deprecations:

    • Gotcha: pomm:default is deprecated in favor of session_builder: "pomm.model_manager.session_builder".
    • Fix: Update config/packages/pomm.yaml:
      pomm:
          configuration:
              default:
                  dsn: "pgsql://..."
                  session_builder: "pomm.model_manager.session_builder"
      
  4. JSONB Query Syntax:

    • Gotcha: PostgreSQL’s JSONB operators (@>, ?, ->) require exact syntax. Common errors:
      // Wrong: Missing quotes around JSON string
      $posts->findWhere('metadata @> $*', ['{"tags": ["laravel"]}']);
      
      // Correct: Use single quotes for JSON strings
      $posts->findWhere("metadata @> $*", ["'{\"tags\": [\"laravel\"]}'"]);
      
    • Tip: Use jsonb_build_object() in queries for complex JSON:
      $posts->findWhere('metadata @> jsonb_build_object("tags", ARRAY["laravel"])');
      
  5. Value Resolver Conflicts:

    • Gotcha: If multiple resolvers claim the same entity, Symfony throws NoSuitableResolverException.
    • Fix: Prioritize the EntityValueResolver by ordering in config/services.yaml:
      services:
          Conserto\PommBundle\ValueResolver\EntityValueResolver:
              tags: [controller.value_resolver, { priority: 10 }]
      

Debugging Tips

  1. Enable Pomm Profiler:

    • Add to config/packages/dev/pomm.yaml:
      framework:
          profiler:
              collectors:
                  pomm: true
      
    • View SQL queries and execution time at /_profiler/pomm.
  2. Log Raw Queries:

    • Configure the logger in config/packages/pomm.yaml:
      pomm:
          logger:
              service: "@monolog.logger.pomm"
      
    • Log queries to var/log/pomm.log:
      use Monolog\Logger;
      
      public function __construct(Logger $pommLogger) {
          $this->pommLogger = $pommLogger;
      }
      
  3. CLI Verbosity:

    • Run commands with -v for debug output:
      php bin/console pomm
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity