私はデータベース内のすべての人を見ることができるページを作成し、それらの編集を作成しようとしています。特定のフィールドのデータベースからデータを入力するフォームを作成しました。
[次へ]ボタンと[前へ]ボタンを使用して、それらをナビゲートしたいと思います。
次のステップを生成するには、現在のIDよりも大きいIDを取得して、次のプロファイルをロードする必要があります。
前のステップを生成するには、現在のIDよりも小さいIDを取得して、前のプロファイルをロードする必要があります。
私のルート:
Route::get('users/{id}','UserController@show');
コントローラー:
public function show($id)
{
$input = User::find($id);
// If a user clicks next this one should be executed.
$input = User::where('id', '>', $id)->firstOrFail();
echo '<pre>';
dd($input);
echo '</pre>';
return View::make('hello')->with('input', $input);
}
表示:ボタン:
<a href="{{ URL::to( 'users/' . $input->id ) }}">Next</a>
現在のIDを取得してインクリメントするための最良の方法は何ですか?
以下は、更新されたコントローラーと@ ridecar2リンクから派生したビューファイルです。
コントローラー:
public function show($id)
{
// get the current user
$user = User::find($id);
// get previous user id
$previous = User::where('id', '<', $user->id)->max('id');
// get next user id
$next = User::where('id', '>', $user->id)->min('id');
return View::make('users.show')->with('previous', $previous)->with('next', $next);
}
表示:
<a href="{{ URL::to( 'users/' . $previous ) }}">Previous</a>
<a href="{{ URL::to( 'users/' . $next ) }}">Next</a>
// in your model file
public function next(){
// get next user
return User::where('id', '>', $this->id)->orderBy('id','asc')->first();
}
public function previous(){
// get previous user
return User::where('id', '<', $this->id)->orderBy('id','desc')->first();
}
// in your controller file
$user = User::find(5);
// a clean object that can be used anywhere
$user->next();
$user->previous();
私はここでuser2581096が取っているアプローチを理解していますが、それが効率的であるかどうかはわかりません(標準によって)。理由もなく、データベースを3回呼び出しています。もっと効率的でスケーラブルな代替案を提案します。
前と次のIDをビューに渡さないでください。これにより、2つの不要なデータベース呼び出しがなくなります。
次のルートを作成します。
users/{id}/next
users/{id}/previous
これらのルートは、アンカータグのhref属性で使用する必要があります
コントローラにメソッドを追加して、作成した新しいルートのそれぞれを処理します。例えば:
public function getPrevious(){
// get previous user
$user = User::where('id', '<', $this->id)->orderBy('id','desc')->first();
return $this->show($user->id);
}
この関数は、実際にボタンをクリックしたときにのみ呼び出されます。したがって、データベースの呼び出しは、実際にユーザーを検索する必要がある場合にのみ行われます。
前のユーザーと次のユーザーを取得するためのより簡単な解決策を見つけました。
public function show($id)
{
$previousUser = User::where('id', '<', $id)->first();
$nextUser = User::where('id', '>', $id)->first();
return View::make('users.show')->with('previous', $previousUser)->with('next', $nextUser);
}
ここに役立つリンクがあります: http://maxoffsky.com/code-blog/laravel-quick-tip-get-previous-next-records/
次に使用したいのは$next = User::where('id', '>', $id)->min('id');
で、ビューは<a href="{{ URL::to( 'users/' . $next->id ) }}">Next</a>
のように見えます。
また、$next
をビューに渡すことを忘れないでください。
最も簡単なアプローチ
// User.php
public static function findNext($id)
{
return static::where('id', '>', $id)->first();
}
// UserController.php
$nextUser = User::findNext($id);
// view
<a href="{{ URL::to( 'users/' . $nextUser->id ) }}">Next</a>
遅延アプローチ:
// view
<a href="{{ URL::to( 'users/' . $input->id . '/next') }}">Next</a>
// routes.php (should be optimized, this is just to show the idea)
Route::get('users/{user}/next', function($id) {
$nextUser = User::findNext($id);
return Redirect::to('user/' . $id);
});
前/次のレコードとそのデータを取得したい場合は、試すことができます
$id = 7; // for example
$prev = DB::table('posts')->where('id', '<', $id)->orderBy('id','desc')->limit(1);
$next = DB::table('posts')->where('id', '>', $id)->limit(1);
$res = DB::table('posts')
->where('id', '=', $id)
->unionAll($prev)
->unionAll($next)
->get();
// now $res is an array of 3 objects
// main, prev, next
dd($res);
1- クエリビルダーは通常、雄弁よりもはるかに高速です。
2-ユニオンを使用すると、3ではなく1回だけdbにヒットします。
コードを開発しました。
次の投稿や前の投稿がない場合でも、常に機能します
public function nextPost($table, $id)
{
$next = DB::table($table)->where('id', '>', $id)->orderBy('id','asc')->first();
if(!$next)
$next = DB::table($table)->orderBy('id','asc')->first();
return $next;
}
public function prevPost($table, $id)
{
$prev = DB::table($table)->where('id', '<', $id)->orderBy('id','desc')->first();
if(!$prev)
$prev = DB::table($table)->orderBy('id','desc')->first();
return $prev;
}