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

Crud Laravel Package

dick/crud

dick/crud is a Laravel package for quickly scaffolding CRUD operations, helping developers generate create, read, update, and delete workflows with less boilerplate and a cleaner, more maintainable codebase. It aims to simplify common admin and data-management tasks so you can focus on application l...

View on GitHub
Deep Wiki
Context7

Getting Started

Pull the package in and let it publish what it needs:

composer require dick/crud
php artisan vendor:publish --provider="Backpack\CRUD\CrudServiceProvider"
php artisan migrate

Add the service provider (and Backpack\Base, Backpack\PermissionManager if you want the admin UI shell and ACL) to config/app.php, then hit /admin — the package registers its own routes via the provider, so you usually don't wire them by hand.

The first thing to look at is the generated controller, not the package source. Scaffold one model to see the shape:

php artisan make:crud Product   # or php artisan backpack:crud Product in later versions

This gives you app/Http/Controllers/Admin/ProductCrudController.php and app/Http/Requests/ProductRequest.php. The controller is where you live 95% of the time. It extends Backpack\CRUD\app\Http\Controllers\CrudController and uses ProductRequest for validation. Open it and you'll see the setModel(), setRoute(), and (depending on version) either an __construct() or setup() method — that's the whole API surface you need for a first CRUD.

First real use case: point a freshly scaffolded CRUD at an existing table, add $this->crud->addColumn('name'); and $this->crud->addField('name');, and you have a working list + create + edit in under a minute. That's the package's entire value proposition — the time from "I have a model" to "I have a working admin" is minutes, not hours.

Implementation Patterns

List vs. form are separate stacks. addColumn() builds the datatable; addField() builds the create/edit form. They look similar but are independent — adding a column doesn't add a field and vice versa. Treat them as two separate declarations.

Field types are the real API. Everything meaningful is a string in the type key: text, textarea, select, select_multiple, select2, date, datetime, image, upload, wysiwyg, number, email, password, hidden, checkbox. When something looks wrong in the UI, check the type first — a text field rendering a date input is a type typo.

Relationships. The 1-n pattern that shows up in almost every CRUD:

$this->crud->addField([
    'name' => 'category_id',
    'type' => 'select2',
    'label' => 'Category',
    'entity' => 'category',   // the relation method name on the model
    'attribute' => 'name',    // which column to display
    'model' => "App\\Models\\Category",
]);

select_multiple needs a pivot key and a real many-to-many relation. When the select is empty, the cause is almost always a missing attribute or a broken relationship.

Fake fields for composite / derived data. For columns that don't map to a DB column (full name, slug preview, a checkbox that toggles two fields), use:

$this->crud->addField([
    'name' => 'full_name',
    'fake' => true,
    'store_in' => 'name',   // or use a mutator
]);

Fake fields are the answer to "I need this in the form but the table doesn't have it." Use them before you start adding columns to the DB.

Overriding store/update. When FormRequest validation isn't enough, override store() and update() on the CRUD controller and call parent after your custom logic. Same for destroy() when there are cascading deletes. This is the clean extension point — you don't need to fork the package.

Row-level buttons and operations. $this->crud->addButtonFromView('line', 'preview', 'preview_button', 'beginning') adds a per-row button. Custom operations (bulk actions, exports) live as traits with a setup() and a run() method — copy a built-in one before writing from scratch.

Views are meant to be overridden. php artisan vendor:publish drops resources/views/vendor/backpack/crud/ into your app. Per-controller overrides use $this->crud->setListView('admin.product.list') — no need to touch the vendor view.

Validation via FormRequest. The scaffolded ProductRequest extends CrudRequest. Add rules there. This keeps validation out of the controller and lets you swap rules per action. Remember to exclude the current record's ID from unique rules on update — the base class gives you the route parameter, but you need to interpolate it yourself.

Gotchas and Tips

  • The dick/crud name is stale. This is early Backpack. Most docs, StackOverflow answers, and examples you find are for backpack/crud 4.x, which renamed __construct() to setup() and split it into setupListOperation(), setupCreateOperation(), etc. If a snippet doesn't work, the version mismatch is the cause — check which method signature your installed version expects before rewriting anything.
  • Mass assignment bites silently. Fields appear in the form but don't save. That's $guarded / $fillable on the model, not the package. Fields marked fake also don't save unless you set store_in or a mutator.
  • Route conflicts with your own admin routes. The package registers /admin/* routes. If you have your own admin area, namespace it differently or use setRoute() on each CRUD to keep them separated. A missing setRoute() is the usual culprit when edit links 404.
  • File and image uploads need a public disk. image / upload fields default to a disk path that doesn't exist out of the box. Set disk and prefix explicitly, run php artisan storage:link, and verify the field has a matching accessor on the model (or you'll show a raw path instead of a URL in the list).
  • Password fields. A password type renders correctly but does not hash. Override store()/update() (or use a mutator) with Hash::make(), otherwise you'll store plaintext and only notice on login.
  • View caching after edits. Custom view changes silently don't appear until you run php artisan view:clear. If you override a view and nothing changes, that's the first thing to check.
  • select_multiple on update. The pivot is synced, but pivot columns are not — if you need extra pivot data, override update() and call sync() with an array yourself.
  • Cache and compiled views live on the vendor side. After a Composer update of the package, always php artisan view:clear and composer dump-autoload. Stale crud:: view references are a common post-update break.
  • Debugging tip: dd($this->crud->getFields()) and dd($this->crud->getColumns()) inside your setup method show exactly what the package thinks it's rendering. Faster than reading views.
  • Extension points to remember. Custom field types: register a view name and add it to the config. Custom operations: a trait with setup() + run(). Custom buttons: a Blade partial via addButtonFromView. Between those three plus store()/update() overrides, you rarely need to touch vendor code.
  • ACL is a separate concern. The core CRUD package doesn't do permissions. If you need role-based access, add backpack/permissionmanager (or your own middleware) — don't try to bolt auth logic into setup(), it gets evaluated at construction time before the request user is reliably available.
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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle