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

Easy Model Laravel Package

ramadan/easy-model

ramadan/easy-model is a Laravel package that simplifies Eloquent model development with convenient helpers and utilities for common model tasks, reducing boilerplate and helping you build clean, maintainable applications faster.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • Laravel-only package that layers a query-management API over Eloquent/Query Builder. v2.1.0 substantially widens its footprint: it now covers read querying, request-driven filtering/sorting/includes/search, eager loading, pagination, soft deletes, mass writes, and SQL introspection.
  • That scope expansion changes the architectural question. This is no longer a thin fluent-sugar wrapper; it is a competing data-access layer with its own conventions for reads, writes, soft deletes, and model events. Adopting it is now closer to choosing a data-access standard than adding a convenience.
  • The package now overlaps almost entirely with mature, widely adopted alternatives (Spatie Laravel Query Builder for the request-driven filter/sort/include surface, plus native Eloquent for the rest). Any adoption case must explain why a bespoke, single-maintainer, near-zero-adoption package is preferable to the established option.
  • The request-driven surface (fromRequest(), allowedFilters(), allowedSorts(), allowedIncludes(), allowedSearch()) is an API-boundary component, not an internal helper. It sits directly on the path from untrusted HTTP input to database queries, which raises the bar for review considerably.
  • usingModelEvents(), performInsert(), and performUpsert() are the most architecturally consequential additions. Bypassing or selectively replaying model events/observers undermines the single most reliable invariant in a Laravel codebase: that writes go through the model layer and fire consistent events. Audit trails, cache invalidation, search indexing, and notification side effects typically hang off those events.

Integration feasibility

  • Still technically trivial: Composer install, auto-discovery, optional config. Hours, not weeks.
  • Adoption posture is unchanged: 11 stars and 0 dependents means no observable production validation. A test suite is a genuine maturity signal, but self-authored tests are not evidence of field hardening — they prove the author's intent, not behavior under real schemas, drivers, and traffic.
  • The release adds an Orchestra Testbench + PHPUnit suite. This directly answers a prior key question and materially de-risks the source review, but the suite's depth is unknown: whether it runs against a real database, covers each driver, and asserts generated SQL versus just return values.
  • The changelog is well-formed and the compare link resolves the version lineage, which is a positive signal for release hygiene. It still does not evidence SemVer discipline, a deprecation policy, or a support commitment across the 2.0 → 2.1 boundary.
  • The previously noted anomalous release date and the package-name/repository-name discrepancy remain unverified and should still be reconciled against the authoritative source.

Technical risk

  • High abandonment risk (unchanged): single maintainer, negligible adoption, no dependents. Score of 18/100 remains consistent with that signal.
  • Scope-creep risk (new and significant): the surface grew from "query wrapper" to "read + write + soft delete + request parsing + event handling" in one minor release. Growing surface with a bus factor of one is the wrong direction; it also invalidates the earlier assumption that a fork would cost days.
  • Untrusted-input-to-query risk (new): fromRequest() plus allowedFilters()/allowedSorts()/allowedIncludes() is a classic injection and data-exfiltration surface. The allow-list model is sound in principle, but the failure mode is severe: an unlisted filter that is not strictly rejected, a sort column that accepts a relation path, or an allowedIncludes() entry that traverses to a sensitive relation can leak data or produce unbounded joins. allowedIncludes() is particularly high-risk because it lets the client shape the query graph.
  • Write-path integrity risk (new): performUpsert() combined with usingModelEvents() implies writes that may not fire observers. Silent divergence between "writes that fire events" and "writes that don't" is exactly the kind of defect that surfaces months later as an audit-trail gap or a stale cache.
  • Soft-delete semantics risk (new): onlyTrashed(), restore(), and forceDelete() are irreversible or hard-to-reverse operations exposed through a convenience API. forceDelete() reachable from a request-driven layer is a serious blast-radius concern.
  • Abstraction leak risk (partially mitigated): toSql() and SQL inspection are a genuine improvement — teams can now see generated SQL without a debugger. That directly addresses the earlier opacity concern and should be used as a review requirement, not just a debugging aid.
  • Upgrade coupling (unchanged): a package pinned to older Laravel/PHP versions can block framework upgrades. The test suite makes this easier to verify, but the supported-version matrix is still unpublished.

Key questions

  1. Which Laravel and PHP versions are supported, and is there a public CI matrix proving it across those versions?
  2. Do the tests run against real MySQL and PostgreSQL, or only SQLite in-memory? Driver-specific behavior is where query wrappers break.
  3. What exactly does fromRequest() do with an unknown filter, sort, or include — throw, ignore, or pass through? The answer determines the security posture.
  4. Does allowedIncludes() bind to an explicit allow-list of relation names, and can it be constrained (per-endpoint, with required parent scopes) or is it global?
  5. What is the precise contract of usingModelEvents() — which events fire, which are suppressed, and do performInsert()/performUpsert() fire creating/created/saving/saved by default or only when opted in?
  6. Is forceDelete() reachable through the request-driven surface, and what guards it?
  7. Does the wrapper produce parameterized SQL for every new filter type, including addWhereJsonContains() and addKeywordSearch() with dotted relation columns? toSql() output should be inspected for bindings versus interpolated values.
  8. Why this package rather than Spatie Laravel Query Builder plus native Eloquent — what is the delta, and is the delta worth the abandonment risk?
  9. Who maintains it, what is the commit cadence, is there a security contact, and is the license compatible with our distribution model? (All still unanswered.)

Integration Approach

Stack fit

  • Only viable on Laravel with Eloquent. No fit for Symfony, plain PHP, or non-Laravel workers.
  • The request-driven surface can only be justified in read-only API endpoints backed by non-sensitive tables. Do not place it anywhere near authorization decisions, financial data, PII, or write paths.
  • Treat performInsert(), performUpsert(), usingModelEvents(), and forceDelete() as out of scope for a pilot. Pilot the read/query surface only; the write and hard-delete additions carry risk disproportionate to their convenience value.

Migration path

  • Do not migrate existing queries or writes. Introduce additively, new code only, in one bounded context.
  • Keep every call behind an internal query-object or repository. The package API must not appear in controllers, domain code, or (especially) in route-level request handling. This preserves a one-file removal path.
  • Explicitly forbid fromRequest() at the framework boundary until the allow-list semantics in question 3 are verified by source review. Accept request input as a validated array and pass explicit parameters instead.
  • For any write path that must fire observers, use native Eloquent regardless of what the package offers. Do not create two write dialects.

Compatibility

  • Build the matrix: Laravel versions, PHP versions, conflicts with Larastan/PHPStan, IDE helper, and any existing query-builder extensions.
  • Verify the test suite actually runs locally against our target versions before trusting the green badge.
  • Confirm that published config keys do not collide, and that auto-discovery is compatible with our service-provider registration.
  • Run the same representative queries against MySQL and PostgreSQL and diff the toSql() output, including bindings.

Sequencing

  1. Source review (2–3 days, up from 1–2): the surface has grown. Focus on the request-parsing path, allow-list enforcement, usingModelEvents() semantics, and every place raw SQL or column names are interpolated.
  2. Security review (new gate): dedicated pass on fromRequest()/allowedIncludes()/allowedSorts() for injection, relation traversal, and unbounded-join exposure. This is the release's highest-risk change and must not be folded into general code review.
  3. Compatibility spike: install in a scratch app on our version, exercise eager loading, pagination variants, soft deletes, and toSql().
  4. Alternatives comparison: benchmark against Spatie Laravel Query Builder plus native Eloquent on the same two or three endpoints. If the bespoke package shows no measurable advantage, stop here.
  5. Risk memo: document generated SQL, the write-event contract, and the fork cost at the new surface area.
  6. Pilot: one non-critical read-only module, new code only, behind an internal interface, with a rollback commit ready.
  7. Review gate: keep only if it demonstrably reduces code volume or defect rate and survives the security review. Otherwise adopt the mature alternative or an internal trait we own.
  8. Fork contingency: the earlier "days to fork" estimate no longer holds. Re-estimate against the v2.1.0 surface before assuming forkability.

Operational Impact

Maintenance

  • Bus factor of one, unchanged. Budget for becoming the maintainer of a fork — but the fork is now materially larger than previously assessed, spanning request parsing, write operations, soft-delete handling, and pagination.
  • The added test suite lowers the cost of forking somewhat (a regression harness exists), which partially offsets the increased surface. Net fork cost is plausibly weeks rather than days.
  • Rapid minor-version scope expansion is itself a maintenance signal: the maintainer is adding capabilities faster than the adoption base can validate them. Expect churn.
  • No dependents means no downstream pressure to fix bugs and no peer-reviewed upgrade paths.

Support

  • Community-only via GitHub issues, with a very small user base. No vendor, no SLA, no visible security advisory process — a sharper concern now that the package parses untrusted input.
  • Internal ownership must be named before adoption: a team accountable for upgrades, security triage, and the allow-list policy itself.
  • The request-driven features need an internal policy, not just an owner: which endpoints may use them, which relations may be included, which columns may be sorted. That policy is ongoing operational work, not a one-time setup.

Scaling

  • Runtime overhead is likely still negligible if the package compiles to the standard query builder; validate with query-log comparison rather than assuming.
  • The scaling risk has shifted from behavioral to structural: allowedIncludes() and dotted-relation keyword search let a client dictate join depth and shape. An unbounded include graph is a denial-of-service vector and a query-plan hazard at volume. Cap includes, require explicit registration, and test against production-scale data.
  • addKeywordSearch() across dotted relation columns is likely to produce unindexed LIKE-style scans across joined tables. Verify the generated SQL before enabling it on any large table.
  • Still no evidence of connection-pooling, read/write splitting, or multi-tenancy awareness. Verify before use in sharded or multi-tenant environments.

Failure modes

  • Package abandoned → framework upgrade blocked → forced fork at a larger surface than budgeted.
  • Allow-list bypass or misconfiguration → data exfiltration via crafted filter/sort/include parameters. Highest-severity new failure mode.
  • allowedIncludes() relation traversal → unbounded join → latency incident or resource exhaustion.
  • Write path using performUpsert() without model events → silent audit-trail gap, stale cache, missed index update.
  • forceDelete() reachable from a convenience API → unrecoverable data loss from a single mistaken call.
  • Unparameterized fragments in the newer JSON/date/keyword helpers → injection exposure. toSql() should be used in review to catch interpolated values.
  • Breaking change in a patch release → silent behavior change in query results.
  • Maintainer account compromise or unpublished tag → supply-chain risk; mitigate with lockfiles, pinned versions, and provenance checks.

Ramp-up

  • Low syntactic learning curve; a developer can be productive in hours.
  • Conceptual cost is now higher, not lower. Engineers must know Eloquent, SQL, and the wrapper's semantics for soft deletes, pagination variants, event firing, and allow-listed request parsing — and must know which layer to reach for in each case.
  • The request-driven features invite a false sense of safety: allowedFilters() looks like a guardrail, and teams will treat it as one whether or not it is. Training must state plainly that allow-lists are a security control requiring review, not a convenience toggle.
  • Unknown documentation quality and effectively nonexistent community Q&A mean onboarding depends on reading source. Plan an internal README covering sanctioned patterns, the write-path prohibition, the include allow-list policy, and one worked example.
  • Overall recommendation: still do not adopt as a platform dependency. v2.1.0 improves the maturity signals (test suite, toSql(), changelog hygiene) but simultaneously expands the blast radius into untrusted input parsing and the write path, and deepens the overlap with a better-supported alternative. A time-boxed read-only spike is justified only after the security review and the Spatie comparison; absent a specific, measured pain point, an internal helper trait or the established package remains the better trade.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource