【问题标题】:Route Model Binding on different database不同数据库上的路由模型绑定
【发布时间】:2019-08-07 06:01:09
【问题描述】:

我有多个数据库,并且作为模型在从路由模型绑定调用时考虑默认连接,它说找不到表。如何将资源控制器编辑/更新方法中的模型绑定为路由模型绑定的一部分,以考虑当前连接而不是默认连接? PS - 我无法在模型上声明 $connection,因为我不知道它会在某个时刻访问哪个数据库。

【问题讨论】:

  • 使用Route::bind(function ($id) { /* custom code */ }); 指定自定义逻辑而不是自动绑定,因为您似乎有无法自动绑定的逻辑。
  • 好的,我这样做了,它正确连接并返回数据。这就是我使用的 - Route::bind('posts', function ($value) { $dbName = session('dbName'); \Config::set('database.connections.tenant.database',$dbName) ; \DB::setDefaultConnection('tenant'); return Posts::find($value); });现在,我觉得这里的问题是,我有很多模型,所以绑定每个模型,无论我觉得要为路由模型绑定制作资源控制器,这将是一项繁重的任务。还有其他方法吗?

标签: laravel


【解决方案1】:

您可以使用路由中间件为特定路由设置数据库连接。为此,您需要在数据库配置中设置连接,然后添加中间件。

我在多租户应用程序中使用类似的设置来管理系统与租户数据库连接。数据库配置:

'connections' => [

   'system' => [
        'driver' => 'mysql',
        'host' => env('DB_HOST', '127.0.0.1'),
        'port' => env('DB_PORT', '3306'),
        'database' => env('DB_DATABASE', 'lms'),
        'username' => env('DB_USERNAME', 'lms'),
        'password' => env('DB_PASSWORD', 'lms'),
        'unix_socket' => env('DB_SOCKET', ''),
        'charset' => 'utf8mb4',
        'collation' => 'utf8mb4_unicode_ci',
        'prefix' => '',
        'strict' => true,
        'engine' => null,
    ],

    'tenant' => [
        'driver' => 'mysql',
        'host' => env('DB_HOST', '127.0.0.1'),
        'port' => env('DB_PORT', '3306'),
        'database' => '',
        'username' => '',
        'password' => '',
        'unix_socket' => env('DB_SOCKET', ''),
        'charset' => 'utf8mb4',
        'collation' => 'utf8mb4_unicode_ci',
        'prefix' => '',
        'strict' => true,
        'engine' => null,
    ],
],

我的示例中的中间件强制使用定义为租户的数据库。

use Closure;
use Illuminate\Support\Facades\Config;

class EnforceTenancy
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        Config::set('database.default', 'tenant');

        return $next($request);
    }
}

然后可以在 kernel.php $routeMiddleware 数组中注册中间件

'tenancy.enforce' => \App\Http\Middleware\EnforceTenancy::class,

然后在你的路由文件中为需要第二个数据库的任何路由应用中间件。

【讨论】:

  • 附注,租户连接详细信息为空白,因为它们是在运行时根据登录的租户设置的,您可以根据需要设置您的数据库详细信息。
  • 我有确切的配置,我已经清空了租户连接,每次请求我都必须在我的自定义 checksession 中间件中设置数据库,我还放入内核并在路由组中使用.一切都完美无缺。唯一中断的是在 Rote Model Binding 时,如果我尝试诸如 public function update(User $user) 之类的东西,我会收到一条错误消息,指出 centraldb.user 不存在。这意味着,它始终采用文档中提到的默认连接。我试图 dd($request) 在我的中间件中,但它没有通过,没有模型绑定它可以工作。
  • 另外,请看一下我的解决方案,我有一个解决方法,但它需要一些输入。
猜你喜欢
  • 2018-02-28
  • 2019-09-24
  • 2016-04-20
  • 1970-01-01
  • 2019-09-05
  • 2019-01-10
  • 2016-06-04
  • 1970-01-01
  • 2017-10-07
相关资源
最近更新 更多