Weave 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

Laravel Crudable Laravel Package

marceauka/laravel-crudable

Laravel CRUDable provides a reusable controller trait for adding create, read, update, and delete actions to Laravel models with minimal boilerplate. Configure the model and fields, and it handles the repetitive CRUD logic so your controllers stay clean and consistent.

View on GitHub
Deep Wiki
Context7

Getting Started

Read the archived notice before anything else. This package is archived and last saw meaningful activity in the Laravel 5.x era. Before writing a line of code, open composer.json in the repo and check the illuminate/* constraints and the php requirement. If you are on Laravel 8+, assume the package will not install cleanly and budget for either a fork or a rewrite.

Minimal steps for an existing codebase that already depends on it:

  1. composer require marceauka/laravel-crudable — pin the exact version in composer.json ("marceauka/laravel-crudable": "1.x" style) so a future composer update cannot pull a surprise.
  2. Confirm service provider registration. On Laravel 5.5+ auto-discovery may cover it; on older versions add it manually to config/app.php. Grep vendor/marceauka/laravel-crudable/src for ServiceProvider to see what it binds.
  3. Run php artisan vendor:publish and inspect what tags appear — config and/or Blade views. If nothing is published, the package is likely config-free and view-free, which tells you it is a thin routing/controller abstraction.
  4. Run php artisan route:list before and after wiring up your first resource. This is the fastest way to learn what the package actually generates, and it is more reliable than the README if the README has drifted.

First use case: wire up exactly one resource end-to-end — a trivial model like Post with title and body. Get index/create/store/edit/update/destroy working against a throwaway table, then read the generated routes and controller flow. Do not attempt to convert your whole app; the value proposition here is boilerplate reduction for simple resources, and you need to see the shape of that boilerplate before deciding whether it fits your conventions.

Where to look first: the README's first code block (canonical entry point), then src/ for the base controller or trait it asks you to extend. The entire package is small enough to read in ten minutes — do that instead of trusting docs.

Implementation Patterns

Extend, don't wrap. Packages of this genre typically give you a base controller (or a trait) that implements the seven resource actions and expects you to override hooks: validation rules, the query used for index, the model class, the view namespace, and redirect targets. Keep your per-resource controllers as thin as possible — overriding store() wholesale defeats the point and makes future Laravel upgrades harder. Override the narrow hooks (rules, scopes, eager loads) and leave the action methods alone.

Co-locate validation with the model. Put $rules (and separate $updateRules if the package supports it) on the Eloquent model or in a rules() method, and have the controller hook read from there. This keeps the rules reusable if you later call the same validation from an API controller or a console command, and it makes the eventual migration off the package mostly a controller swap.

Layer authorization outside the package. Do not rely on the package for access control. Register a Policy per model and call $this->authorize(...) from a single overridden hook or from middleware on the generated routes. Archived packages rarely receive security fixes, so nothing security-relevant should live inside its action methods.

Use route groups for cross-cutting concerns. Since the package owns route generation, wrap its route registrations in a Route::middleware([...])->prefix(...)->group(...) block rather than editing each generated route. This is also where you bolt on auth, throttling, and can: middleware.

Scope index queries explicitly. A generic index almost always does Model::all() or Model::paginate(). In a multi-tenant or soft-deleted app that is a data leak waiting to happen. Override the query hook to apply tenant scoping, with() eager loads, and default ordering — and write a feature test asserting a user from tenant A cannot see tenant B's rows through the generated index route.

Testing pattern. Since the routes are generated, test at the HTTP layer, not the controller layer. A ResourceCrudTest trait that takes a model factory and asserts the six routes behave (200 on index, 302 on store, 403 for unauthorized) gives you coverage across every resource with one class. This is the single highest-leverage thing you can build around the package.

Migration insurance. If you expect to leave the package, keep a thin App\Http\Controllers\ResourceController base of your own that the package-backed controllers extend. When you drop the dependency, you change one file's extends target instead of every controller.

Gotchas and Tips

  • Archived means no Laravel 10/11 support. Check the illuminate/support constraint first. If it caps below your Laravel version, Composer will either refuse to install or (worse, with --ignore-platform-reqs) install something that fatals at runtime. Fork it, bump the constraints, and run the test suite before trusting it.
  • Mass assignment silently drops fields. Generic store/update typically call create($request->all()). If a field isn't in $fillable, it vanishes with no error. When a form "saves" but a column stays null, check $fillable before you debug the request.
  • Route model binding vs. manual lookups. If the package resolves records itself rather than via implicit binding, {model} route parameters and soft-deleted records behave differently than you expect. Confirm with route:list --columns=uri,action and a dd() in the overridden hook.
  • Published views shadow package views. Once you publish Blade stubs, upgrades to the package (unlikely here, but relevant if you fork) will not update them. Note the publish date in a comment. Conversely, if you don't publish, customizing markup requires overriding the view name hook rather than editing files.
  • Method signature mismatches on override. In old packages, base methods are often protected function store(Request $request) or lack type hints. Adding a return type or changing visibility in your override causes a fatal error that reads like a mystery. Match the parent signature exactly, or you'll spend an hour on it.
  • Debugging "route not found". The registration mechanism is usually a route macro or a service-provider loop over a config array. If routes don't appear in route:list, the provider isn't registered, the macro is registered after your routes file loads, or the config cache is stale — run php artisan route:clear && php artisan config:clear before anything else.
  • Config caching in production. Any config-array-driven route generation must be cache-safe. Verify php artisan config:cache && php artisan route:cache still produces the same route:list output; a package that does config() lookups at request time or uses closures in routes will break route:cache entirely.
  • Extension points to prefer, in order: (1) override narrow hooks, (2) publish and edit config/views, (3) subclass the base controller in your own namespace, (4) fork the package. Reaching for (4) is a signal to instead reimplement the six resource methods by hand — it's roughly 40 lines with Route::resource and buys you full framework support.
  • The honest recommendation: at 39 stars and archived, the risk/reward is poor for new work. php artisan make:controller --resource --model=Post plus a FormRequest gets you 80% of the same benefit with zero dependency risk. Reserve this package for maintaining an app that already uses it, and use the maintenance window to plan the extraction.
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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings