所以@Chris建議了一個專門的關係控制器,而@RossWilson有一種天才的方式來重新使用控制器來處理關係(至少對於加載Book
的行爲)。
不幸流明的RouteProvider
返回一個簡單的數組,因此不具有$request->route($param)
方便,更重要的是,$request->route()->forgetParameter($param)
。
===新的解決方案===
我落得這樣做基本上爲@RossWilson建議完全一樣,只是在被流明支持的方式。我沒有在控制器的__construct
中獲得路由參數,而是創建了一箇中間件,將路由參數移動到請求的輸入和查詢數組上。
中間件看起來是這樣的:
public function handle($request, $next)
{
if ($genre_id = Arr::get($request->route()[2], 'genre')) {
// Add 'genre_id' to the input array (not replacing it if it already exists).
$request->merge(['genre_id' => $request->input('genre_id', $genre_id)]);
// Add 'genre_id' to the query array.
$request->query->add('genre_id', $genre_id);
// Forget the route parameter
// Has to be done manually, because Lumen...
$route = $request->route();
$request->setRouteProvider(function() use ($route) {
Arr::forget($route[2], 'genre');
return $route;
});
}
// Pass the updated $request to $next.
return $next($request);
}
我在執行我只能爲GET
和DELETE
請求的查詢參數,並輸入參數POST
和PUT
。
然後,您可以重新使用BookController
作爲genre.book
資源,從$request->query('genre_id')
過濾並關聯$request->input('genre_id')
的關係。
===原液===
相反,我結束了一個與專用控制器的關係GenreBookController
,從非關係控制器BookController
繼承。由於需要匹配的方法聲明(請參閱下面的$book_id = null
以解決此問題),但它不夠精美,但它非常纖薄而乾燥。
GenreBookController extends BookController
:
protected function addGlobalScope($genre_id)
{
// Thanks Ross Wilson for the global scope suggestion.
Book::addGlobalScope('genreScope', function ($query) use ($genre_id) {
$query->where('genre_id', $genre_id);
});
}
public function show(Request $request, $genre_id, $book_id = null)
{
$this->addGlobalScope($genre_id);
return parent::show($request, $book_id);
}
和BookController的,展現的方法是照常營業(它並不需要知道有關show
額外參數)。
我也想出了一個簡單的方式爲GenreBookController
通過類型參數傳遞給store
方法:
public function store(Request $request, $genre_id)
{
// This way lets an input genre_id override the Route parameter.
$request->merge(['genre_id' => $request->input('genre_id', $genre_id)]);
// This way forces the Route parameter to be used over input parameters.
$request->merge(['genre_id' => $genre_id]);
return parent::store($request);
}
,並再次,爲BookController
是企業像往常一樣,當然它可能作出的任何通過$request->input('genre_id')
的流派的驗證/授權。這樣就沒有重複的驗證和授權邏輯。
了一份關於FormRequests
如果使用FormRequests驗證genre_id
,確認發生的GenreBookController
才能從路由參數設置genre_id
輸入變量。
當我看到它,你有兩個選擇:
- 使用中間件路線參數移動到請求輸入。
- 把它放在你的
FormRequest
的authorize
方法中(我沒有測試過,因爲我不喜歡把這種邏輯放在這裏)。
Laravel:如果你不使用流明,我建議考慮看看@ RossWilson的答案,這在我看來是一個小清潔。
您genre.books的輸出是否與'books'相同,但是它的作用範圍是'genre',或者您將包含其他信息。另外,你會想要從'genre.books'創建一個完整的資源嗎?還是隻是'index'和'show'方法? –
另外,您使用的是什麼版本的Laravel? –
@RossWilson我正在使用Lumen/Laravel 5.4。我希望我想返回相同的結果,並且我喜歡使'store'和'update'方法一致的想法,但我不想結束太多不必要的複雜性。 – Zoon