Laravel子类模型的模型绑定

Laravel Model binding of subclass model

我在路由模型绑定我的 Eloquent 子类时遇到了一些问题。以下代码工作正常:

$repo = new \App\Repositories\Eloquent\PluginRepository();
$plugin = $repo->findOrFail(1);
var_dump($plugin->type);

输出

object(App\PluginsTypes)#360 (26) {...}

但是当我绑定模型时,像这样:

routes/web.php

Route::resource('plugins', 'PluginsController');

app/Http/Controllers/Admin/PluginsController.php

public function edit(PluginRepositoryInterface $plugin){
    var_dump($plugin); // object(App\Repositories\Eloquent\PluginRepository)#345 (26) {...}
    var_dump($plugin->id); // NULL
}

所以问题是,它没有找到路由中传递的 id。


在Laravel项目中添加代码:

app/Plugins.php

<?php

namespace App;

class Plugins extends Model{
    // My Eloquent Model

    /**
     * The foreignKey and ownerKey needs to be set, for the relation to work in subclass.
     */
    public function type(){
        return $this->belongsTo(PluginsTypes::class, 'plugin_type_id', 'id');
    }
}

app/Repositories/SomeRepository.php

<?php

namespace App\Repositories;

use App\Abilities\HasParentModel;

class PluginsRepository extends Plugins{
    protected $table = 'some_table';

    use HasParentModel;
}

config/app.php

'providers' => [
    ...
    App\Repositories\Providers\PluginRepositoryServiceProvider::class,
    ...
]

app/Repositories/Providers/PluginRepositoryServiceProvider.php

<?php

namespace App\Repositories\Providers;

use Illuminate\Support\ServiceProvider;

class PluginRepositoryServiceProvider extends ServiceProvider{

    /**
     * This registers the plugin repository - added in app/config/app.php
     */
    public function register(){
        // To change the data source, replace the concrete class name with another implementation
        $this->app->bind(
            'App\Repositories\Contracts\PluginRepositoryInterface',
            'App\Repositories\Eloquent\PluginRepository'
        );
    }
}

一直在使用这些资源:

HasParentModel Trait on GitHub

Extending Models in Eloquent

我在文档中找到了答案(当然):

https://laravel.com/docs/5.6/routing#route-model-binding 自定义解析逻辑

部分

在我的 app/Repositories/Providers/PluginRepositoryServiceProvider.php 中,我在我的接口绑定下添加了以下内容,现在可以使用了。

$this->app->router->bind('plugin', function ($value) {
        return \App\Repositories\Eloquent\PluginRepository::where('id', $value)->first() ?? abort(404);
});

我可能会重命名它,但它很有魅力 :) 美好的一天...