Models
Overview
Pyle provides a number of Eloquent Models and quite often in custom applications you will want to add your own relationships and functionality to these models.
WARNING
We highly suggest using your own Eloquent Models to add additional data, rather than trying to change fields on the core Pyle models.
Replaceable Models
All Pyle models are replaceable, this means you can instruct Pyle to use your own custom model, throughout the ecosystem, using dependency injection.
Registration
We recommend registering your own models for your application within the boot method of your Service Provider.
When registering your models, you will need to set the Pyle model's contract as the first argument then your own model implementation for the second.
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
\Pyle\Facades\ModelManifest::replace(
\Pyle\Models\Contracts\Product::class,
\App\Model\Product::class,
);
}Registering multiple Pyle models.
If you have multiple models you want to replace, instead of manually replacing them one by one, you can specify a directory for Pyle to look in for Pyle models to use. This assumes that each model extends its counterpart model i.e. App\Models\Product extends Pyle\Models\Product.
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
\Pyle\Facades\ModelManifest::addDirectory(
__DIR__.'/../Models'
);
}Route binding
Route binding is supported for your own routes and simply requires the relevant contract class to be injected.
Route::get('products/{id}', function (\Pyle\Models\Contracts\Product $product) {
$product; // App\Models\Product
});Relationship support
If you replace a model which is used in a relationship, you can easily get your own model back via relationship methods. Assuming we want to use our own instance of App\Models\ProductVariant.
// In our service provider.
public function boot()
{
\Pyle\Facades\ModelManifest::replace(
\Pyle\Models\Contracts\ProductVariant::class,
\App\Model\ProductVariant::class,
);
}
// Somewhere else in your code...
$product = \Pyle\Models\Product::first();
$product->variants->first(); // App\Models\ProductVariantStatic call forwarding
If you have custom methods in your own model, you can call those functions directly from the Pyle model instance.
Assuming we want to provide a new function to a product variant model.
<?php
namespace App\Models;
class ProductVariant extends \Pyle\Models\ProductVariant
{
public function someCustomMethod()
{
return 'Hello!';
}
}// In your service provider.
public function boot()
{
\Pyle\Facades\ModelManifest::replace(
\Pyle\Models\Contracts\ProductVariant::class,
\App\Model\ProductVariant::class,
);
}Somewhere else in your app...
\Pyle\Models\ProductVariant::someCustomMethod(); // Hello!
\App\Models\ProductVariant::someCustomMethod(); // Hello!Observers
If you have observers in your app which call observe on the Pyle model, these will still work as intended when you replace any of the models, this means if you want to add your own custom observers, you can just reference the Pyle model and everything will be forwarded to the appropriate class.
\Pyle\Models\Product::observe(/** .. */);Dynamic Eloquent Relationships
If you don't need to completely override or extend the Pyle models using the techniques above, you are still free to resolve relationships dynamically as Laravel provides out the box.
e.g.
use Pyle\Models\Order;
use App\Models\Ticket;
Order::resolveRelationUsing('ticket', function ($orderModel) {
return $orderModel->belongsTo(Ticket::class, 'ticket_id');
});See https://laravel.com/docs/eloquent-relationships#dynamic-relationships for more information.