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 Model Manager Laravel Package

conserto/pomm-model-manager

Pomm ModelManager adds a lightweight model layer for PostgreSQL in Pomm: built-in CRUD plus count/exists, flexible entities, embedded entity conversion, and transactional model computations with advanced Postgres transaction settings. Not an ORM.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require conserto/pomm-model-manager
    

    Requires pomm-project/pomm (≥v4.0) and PHP ≥8.1.

  2. Basic Configuration Define a Pomm connection in config/database.php:

    'pomm' => [
        'default' => [
            'dsn' => 'pgsql:host=localhost;dbname=test',
            'user' => 'user',
            'password' => 'pass',
        ],
    ],
    
  3. First Model Extend Conserto\PommModelManager\ModelManager and define a table:

    use Conserto\PommModelManager\ModelManager;
    use PommProject\Pomm\Adapter\PostgreSql\PostgreSqlAdapter;
    
    class User extends ModelManager
    {
        protected $table = 'users';
        protected $adapter = PostgreSqlAdapter::class;
        protected $primaryKey = 'id';
    }
    
  4. First Query

    $user = User::find(1);
    $users = User::all();
    

Where to Look First

  • Documentation: Check the GitHub README for quick-start examples.
  • ModelManager Class: Review src/ModelManager.php for core methods (find(), create(), update(), etc.).
  • Adapter-Specific Logic: Inspect src/Adapter/ for PostgreSQL/MySQL/SQLite implementations.

Implementation Patterns

Common Workflows

CRUD Operations

// Create
$user = User::create(['name' => 'John', 'email' => 'john@example.com']);

// Read
$user = User::find(1);
$users = User::where('active', true)->get();

// Update
$user->update(['email' => 'new@example.com']);

// Delete
$user->delete();

Query Building

Leverage Pomm’s query builder via fluent methods:

$activeUsers = User::query()
    ->where('active', true)
    ->orderBy('created_at', 'desc')
    ->limit(10)
    ->get();

Relationships

Define has-one/many via belongsTo()/hasMany():

class Post extends ModelManager
{
    public function user()
    {
        return $this->belongsTo(User::class, 'user_id');
    }
}

Eager-load relationships:

$posts = Post::with('user')->get();

Transactions

Wrap operations in a transaction:

User::transaction(function () {
    $user = User::create([...]);
    $user->posts()->create([...]);
});

Events & Observers

Use Pomm’s event system for hooks:

User::creating(function ($model) {
    $model->setAttribute('created_at', now());
});

Integration Tips

  1. Service Providers Bind the manager to the container in AppServiceProvider:

    $this->app->singleton(User::class, function ($app) {
        return new User($app['pomm.connection']);
    });
    
  2. Eloquent-Like Facades Create a facade for convenience:

    // UserFacade.php
    class UserFacade extends Facade {
        protected static function getFacadeAccessor() { return User::class; }
    }
    

    Register in config/app.php:

    'aliases' => [
        'User' => Conserto\Facades\UserFacade::class,
    ],
    
  3. Custom Adapters Extend ModelManager for domain-specific logic:

    class AuditLog extends ModelManager
    {
        protected $table = 'audit_logs';
        protected $fillable = ['action', 'user_id', 'changes'];
    
        public function log($action, array $changes)
        {
            return $this->create([
                'action' => $action,
                'user_id' => auth()->id(),
                'changes' => json_encode($changes),
            ]);
        }
    }
    

Gotchas and Tips

Pitfalls

  1. Adapter Mismatch

    • Ensure the $adapter class matches your database (e.g., PostgreSqlAdapter for PostgreSQL).
    • Fix: Verify pomm-project/pomm adapter compatibility.
  2. Primary Key Assumptions

    • The package assumes $primaryKey is defined. Omitting it may cause silent failures.
    • Fix: Always specify protected $primaryKey = 'id'; unless using a composite key.
  3. Mass Assignment Risks

    • Unlike Eloquent, pomm-model-manager does not auto-fill mass-assignable attributes.
    • Fix: Explicitly define $fillable or use create(['attr' => 'value']) safely.
  4. Lazy-Loading Relationships

    • Relationships are lazy-loaded by default. Over-eager loading can bloat queries.
    • Fix: Use with() selectively or implement load() for explicit loading.
  5. Transaction Rollback

    • Pomm transactions do not auto-rollback on exceptions by default.
    • Fix: Wrap in try-catch or use PommProject\Pomm\Transaction\TransactionManager.

Debugging

  1. Query Logging Enable Pomm’s query logging:

    $connection = Pomm::connection();
    $connection->getLogger()->setLevel(\Monolog\Logger::DEBUG);
    
  2. Schema Mismatches

    • If queries fail with "column not found," verify:
      • The table name ($table) matches the database.
      • Column names in queries match the schema.
  3. Connection Issues

    • Check config/database.php for correct DSN and credentials.
    • Test the connection manually:
      $conn = Pomm::connection();
      $conn->execute('SELECT 1');
      

Configuration Quirks

  1. Default Connection The package uses Laravel’s default database connection. Override via:

    User::on('pomm_secondary')->find(1);
    
  2. Caching Queries Pomm’s query cache is not enabled by default. Enable via:

    $connection->setQueryCache(new \PommProject\Pomm\Cache\QueryCache());
    
  3. Timezone Handling Pomm uses the system timezone. Force Laravel’s timezone:

    date_default_timezone_set(config('app.timezone'));
    

Extension Points

  1. Custom Query Builder Extend Conserto\PommModelManager\Query\Builder to add domain-specific methods:

    class CustomQueryBuilder extends Builder
    {
        public function activeOnly()
        {
            return $this->where('is_active', true);
        }
    }
    

    Override in your model:

    protected $queryBuilder = CustomQueryBuilder::class;
    
  2. Model Events Use Pomm’s event system for pre/post hooks:

    User::addListener('beforeInsert', function ($model) {
        $model->setAttribute('slug', Str::slug($model->name));
    });
    
  3. Serialization Override toArray() for custom serialization:

    public function toArray()
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->email,
            'created_at' => $this->created_at->format('Y-m-d'),
        ];
    }
    
  4. Soft Deletes Implement soft deletes via a trait:

    trait SoftDeletes
    {
        protected $deletedAt = 'deleted_at';
    
        public static function bootSoftDeletes()
        {
            static::addGlobalScope('softDeletes', function (Builder $builder) {
                $builder->whereNull($builder->getModel()->deletedAt);
            });
        }
    
        public function delete()
        {
            $this->setAttribute($this->deletedAt, now());
            $this->save();
        }
    }
    
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
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
christhompsontldr/laravel-inky