如何根据路由参数将模型实例传递给所有控制器和视图
How to pass a model instance to all controllers and views based on a route parameter
我正在开发一个 Laravel 控制面板项目,我们应该能够从一个站点切换到另一个站点,并根据路由中传递的 ID 获取站点的详细信息。
这本身很容易做到,但由于我将有多个控制器使用此技术,这意味着对于每个控制器和每个控制器实例,我将收集站点实例,并且由于多次重复。
这是我的资料:
路线:
Route::get(
'cp/site/{website}/modules/feeds',
'App\Http\Controllers\Modules_sites\Feeds\FeedController@index'
)->name('module_site.feeds.index');
型号:
class Website extends Model
{
use HasFactory;
protected $primaryKey ='site_id';
}
数据库很简单,有一个id(site_id)和name
控制器:
public function index(Website $website)
{
dd($website -> name);
}
上面的工作正常,但我将以跨多个控制器的数十种方法做同样的事情结束,如果需要更改怎么办。
我查看了使用 AppServiceProvider
创建 Website
实例的 ID,然后将其传递给控制器和视图,但我无法执行此操作,因为未定义路由在这个阶段,我似乎只能将其传递给视图。
本质上,我希望创建类似于 auth()->user()
方法的方法,该方法可从控制器和路由中获得,而无需将其传递给每个控制器。
这可能吗?
因为你的主键不是 id
所以它不会自动工作你需要告诉 laravel 按列名搜索
代码将是
Route::get('cp/site/{website:site_id}/modules/feeds', 'App\Http\Controllers\Modules_sites\Feeds\FeedController@index')->name('module_site.feeds.index');
你需要使用{website:site_id}
参考 link https://laravel.com/docs/8.x/routing#customizing-the-default-key-name
也许你可以使用中间件来设置这个值?像这样把它放在全局会话中:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class CheckWebsite
{
public function handle(Request $request, Closure $next): mixed
{
$request->session()->put("website", $request->route("website"));
return $next($request);
}
}
或者基于每个控制器:
<?php
namespace App\Http\Controllers\Modules_sites\Feeds;
use App\Http\Controllers\Controller;
use Closure;
use Illuminate\Http\Request;
class FeedController extends Controller
{
public function __construct()
{
$this->middleware(function (Request $request, Closure $next) {
$this->website = $request->route("website");
return $next($request);
});
}
public function index()
{
dd($this->website->name);
}
}
另外值得一提的是,路由不再像 Laravel 8 中那样定义。它应该是这样的:
Route::get(
'cp/site/{website}/modules/feeds',
[FeedController::class, 'index']
)->name('module_site.feeds.index');
通过适当导入控制器 class。
我正在开发一个 Laravel 控制面板项目,我们应该能够从一个站点切换到另一个站点,并根据路由中传递的 ID 获取站点的详细信息。
这本身很容易做到,但由于我将有多个控制器使用此技术,这意味着对于每个控制器和每个控制器实例,我将收集站点实例,并且由于多次重复。
这是我的资料: 路线:
Route::get(
'cp/site/{website}/modules/feeds',
'App\Http\Controllers\Modules_sites\Feeds\FeedController@index'
)->name('module_site.feeds.index');
型号:
class Website extends Model
{
use HasFactory;
protected $primaryKey ='site_id';
}
数据库很简单,有一个id(site_id)和name
控制器:
public function index(Website $website)
{
dd($website -> name);
}
上面的工作正常,但我将以跨多个控制器的数十种方法做同样的事情结束,如果需要更改怎么办。
我查看了使用 AppServiceProvider
创建 Website
实例的 ID,然后将其传递给控制器和视图,但我无法执行此操作,因为未定义路由在这个阶段,我似乎只能将其传递给视图。
本质上,我希望创建类似于 auth()->user()
方法的方法,该方法可从控制器和路由中获得,而无需将其传递给每个控制器。
这可能吗?
因为你的主键不是 id
所以它不会自动工作你需要告诉 laravel 按列名搜索
代码将是
Route::get('cp/site/{website:site_id}/modules/feeds', 'App\Http\Controllers\Modules_sites\Feeds\FeedController@index')->name('module_site.feeds.index');
你需要使用{website:site_id}
参考 link https://laravel.com/docs/8.x/routing#customizing-the-default-key-name
也许你可以使用中间件来设置这个值?像这样把它放在全局会话中:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class CheckWebsite
{
public function handle(Request $request, Closure $next): mixed
{
$request->session()->put("website", $request->route("website"));
return $next($request);
}
}
或者基于每个控制器:
<?php
namespace App\Http\Controllers\Modules_sites\Feeds;
use App\Http\Controllers\Controller;
use Closure;
use Illuminate\Http\Request;
class FeedController extends Controller
{
public function __construct()
{
$this->middleware(function (Request $request, Closure $next) {
$this->website = $request->route("website");
return $next($request);
});
}
public function index()
{
dd($this->website->name);
}
}
另外值得一提的是,路由不再像 Laravel 8 中那样定义。它应该是这样的:
Route::get(
'cp/site/{website}/modules/feeds',
[FeedController::class, 'index']
)->name('module_site.feeds.index');
通过适当导入控制器 class。