From superpowers-sage
Provides Eloquent ORM models, migrations, and relationships for custom and WordPress tables via Acorn. Includes scripts for creating models and running migrations.
How this skill is triggered — by the user, by Claude, or both
Slash command
/superpowers-sage:acorn-eloquentThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
| Use case | Use Eloquent | Use WordPress functions |
| Use case | Use Eloquent | Use WordPress functions |
|---|---|---|
| Custom tables (event logs, testimonials, form entries) | Yes | No |
| Complex joins across custom tables | Yes | No |
| Relationships between custom models | Yes | No |
| Post types, taxonomies, menus | No | Yes (WP_Query, get_posts) |
| User management, roles, capabilities | No | Yes (wp_insert_user, get_userdata) |
| Options, transients | No | Yes (get_option, get_transient) |
Complex read queries on wp_posts | Read-only, carefully | Prefer WP_Query first |
Rule: WordPress-managed content goes through WordPress functions so hooks fire. Custom application data goes through Eloquent.
# Create a model (PascalCase name required)
bash skills/acorn-eloquent/scripts/create-model.sh Testimonial
# Create a model with a migration
bash skills/acorn-eloquent/scripts/create-model.sh EventLog --migration
# Run pending migrations
bash skills/acorn-eloquent/scripts/run-migration.sh
# Run with additional flags (passed through to lando acorn migrate)
bash skills/acorn-eloquent/scripts/run-migration.sh --seed
bash skills/acorn-eloquent/scripts/run-migration.sh --step=2
Scripts: scripts/create-model.sh · scripts/run-migration.sh
Models live in app/Models/. Always declare $table explicitly with the WordPress prefix.
class Testimonial extends Model
{
use HasFactory;
protected $table = 'wp_testimonials';
protected $fillable = ['author_name', 'company', 'body', 'rating', 'is_featured', 'published_at'];
protected $casts = [
'rating' => 'integer',
'is_featured' => 'boolean',
'published_at' => 'datetime',
'metadata' => 'array',
];
}
See references/models.md for:
$primaryKey, $keyType, $incrementing)Attribute::make()Boilerplate templates with {{PLACEHOLDER}} tokens:
$table, $primaryKey, $timestamps, $fillable, $casts. Replace {{CLASS_NAME}}, {{TABLE_NAME}}.$primaryKey = 'ID', $timestamps = false, write guards. Replace {{CLASS_NAME}}, {{WP_TABLE}}.lando acorn make:migration create_testimonials_table
lando acorn migrate
lando acorn migrate:status
lando acorn migrate:rollback
return new class extends Migration
{
public function up(): void
{
Schema::create('wp_testimonials', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id')->nullable();
$table->string('author_name');
$table->text('body');
$table->unsignedTinyInteger('rating')->default(5);
$table->boolean('is_featured')->default(false);
$table->timestamp('published_at')->nullable();
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('wp_testimonials');
}
};
See references/migrations.md for:
class Testimonial extends Model
{
public function author(): BelongsTo
{
return $this->belongsTo(User::class, 'user_id');
}
public function tags(): BelongsToMany
{
return $this->belongsToMany(Tag::class, 'wp_testimonial_tag', 'testimonial_id', 'tag_id');
}
}
Eager load to avoid N+1:
Testimonial::with('author', 'tags')->get();
See references/relationships.md for:
wp_posts → wp_postmeta (hasMany with ID key)wp_terms → wp_termmetawp_users for read-only relationshipspublic function scopePublished(Builder $query): void
{
$query->whereNotNull('published_at')
->where('published_at', '<=', now());
}
public function scopeMinRating(Builder $query, int $rating): void
{
$query->where('rating', '>=', $rating);
}
Chain fluently:
Testimonial::published()->featured()->minRating(4)->with('author')->get();
See references/query-scopes.md for:
booted() registrationwithoutGlobalScope() usage->when()lando acorn make:factory TestimonialFactory
class TestimonialFactory extends Factory
{
protected $model = Testimonial::class;
public function definition(): array
{
return [
'author_name' => fake()->name(),
'body' => fake()->paragraphs(2, asText: true),
'rating' => fake()->numberBetween(1, 5),
'is_featured' => fake()->boolean(20),
'published_at' => fake()->optional(0.8)->dateTimeBetween('-1 year'),
];
}
}
Testimonial::factory()->count(10)->create();
Testimonial::factory()->featured()->count(3)->create();
Seed:
lando acorn db:seed --class=TestimonialSeeder
See references/factories.md for:
featured(), unpublished())fake() helper referenceDatabaseSeeder registration$timestamps = false for WP core tables (wp_posts, wp_users) — they have no created_at/updated_at.$table explicitly for every model — avoid Eloquent's table name guessing with WP prefix.wp_insert_post(), wp_update_post(), update_post_meta() so hooks fire.lando acorn migrate — never write raw SQL directly.$fillable explicitly — never use $guarded = []; list only known, safe attributes.::with() or ->load() to prevent N+1 queries in loops.lando acorn migrate:status and confirm all migrations show as "Ran".lando acorn tinker to verify: App\Models\Testimonial::first() returns data from the correct table.App\Models\Testimonial::with('author')->first() returns related data without errors.See references/troubleshooting.md for all failure modes and escalation paths.
Deep content loaded on demand — zero tokens until needed.
$table, $fillable, $casts, custom primary key, $timestamps = false for WP tables, accessors.Schema::create, column types reference, up()/down(), running via lando acorn migrate.hasMany, belongsTo, belongsToMany, WP-specific: Post → PostMeta, Term → TermMeta, polymorphic.HasFactory, definition(), fake() reference, states, seeding with lando acorn db:seed.withoutGlobalScope(), conditional ->when(), raw queries.wp_posts, wp_postmeta, etc.), read-only reporting, canonical patterns.superpowers-sage:wp-performance for eager loading strategies.wp_insert_post(), update_post_meta(), wp_insert_user().npx claudepluginhub hekivo/superpowers-sageComplete Eloquent ORM - models, relationships, queries, casts, observers, factories. Use when working with database models.
Provides expert Laravel patterns for PHP 8.2+ including Eloquent ORM best practices, N+1 prevention, efficient queries, atomic operations, query optimization, and RESTful API controllers.
Applies Laravel Eloquent best practices for query optimization, eager loading to avoid N+1, relationships, mass assignment protection, casts, and chunking large datasets.