Download the PHP package stancl/laravel-hasmanywithinverse without Composer

On this page you can find all versions of the php package stancl/laravel-hasmanywithinverse. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package laravel-hasmanywithinverse

stancl/laravel-hasmanywithinverse

Why?

Jonathan Reinink wrote a great blog post about Optimizing circular relationships in Laravel

By manually setting the (belongsTo) relationship to a parent model on related (hasMany) child models, you can save unnecessary queries for the parent model -- when the child needs an instance of the parent model.

This probably sounds confusing, so just read the blog post. It's very good.

Jonathan's approach suggests using something like this:

This works, but it's not very clean and there are cases when it doesn't work. For example, on model creation.

If you're accessing the parent model in creating and saving events on the children, the ->each->setRelation() approach won't help you at all. (And if you're building a complex app with Laravel Nova, there's a high chance you're using lots of such events.)

Practical Example & Benchmarks

I have an e-commerce application where an Order has child models: OrderProduct, OrderStatus and OrderFee (think shipping costs, payment fees, etc).

When some of those models are being created (creating Eloquent event), they are accessing the parent model.

For example, OrderProducts convert their prices to $this->order->currency. OrderFees check for other order fees, and they prevent creating themselves if a fee with the same code already exists (so that you can't have, say, the shipping cost counted twice). Etc.

This results in order creation being expensive, resulting in a large amount of n+1 queries.

Benchmark

I haven't run a huge amount of tests, so I won't present the time differences here. I will only talk about database query count.

I have created an order with 6 products.

This is the amount of queries made with regular hasMany()

Query count with hasMany()

And now I just replace all of these calls:

with these calls

inside the Order model.

And this is the amount of queries made with hasManyWithInverse()

Query count with hasManyWithInverse()

See the query count reduction.

The duration was also decreased from 114ms to 45ms on my machine, though note that I did not run this test a million times to calculate an average duration, so that benchmark might not be very accurate.

This is pretty impressive for a free improvement that only requires changing a few simple calls to a similar method.

But note that this is not a silver bullet for solving all n+1 queries. As you can see, even with this implemented, my app still has many duplicated queries. (Although not all are unintentional n+1s as there are a few $this->refresh() calls to keep the order up-to-date after state transitions).

Installation

Laravel 9.x and 10.x are supported.

Usage

You may also want to use the trait in a base Eloquent model and then use $this->hasManyWithInverse() without thinking about traits in the specific models.

Details

The (simple) internals of the package are just methods copied from Eloquent source code, with a few lines added to them. The hasManyWithInverse() method signature is the same as hasMany() (you can set $foreignKey and $localKey), except the second argument ($inverse) was added to let you define the name of the relationship on the child model, and the last argument ($config) was added to let you configure the relation setting's behavior.

This package sets the parent relation on children both when creating children ($child = $parent->children()->create()) and when resolving parent's children ($children = $parent->children). You can customize this behavior for every relationship.

To disable setting the relationship during child creation, do this:

To disable setting the relationship during child resolution, do this:

You may also pass a callable as the config value. This is useful if you want to disable this behavior on some requests. See example below.

Laravel Nova

It's a good idea to disable setting the relationship on resolution for Nova requests. They tend to make a lot of queries and this can slow the page down (or result in 502 errors).

Here's an example implementation using a base model and adding config to filter out Nova requests.


All versions of laravel-hasmanywithinverse with dependencies

PHP Build Version
Package Version
Requires illuminate/database Version ^9.0|^10.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package stancl/laravel-hasmanywithinverse contains the following files

Loading the files please wait ....