Fippiyのプログラム学習内容アウトプットBlog

日々の学習内容をアウトプットして振り返りを実施する。

Laravel開発、ページネーション機能をつける【4】所有書籍ページをページネーション対応にする

ページネーション対応させたコンポーネントですが、所有書籍ページでも利用をしています。

しかし、所有書籍ページではまだ未対応だった為に、ページ表示が正常にできない状態です。

このまま本番環境を更新するわけにもいきませんので、所有書籍ページについてもページネーション対応を実施します。

今回の目的

所有書籍情報ページにてページネーション対応 を行う

なぜやるか

コンポーネントがページネーション仕様となり、コントローラーとの情報に差分が発生しており、ビュー表示にエラーが発生するので、解消させるため。

やりたいこと

所有書籍一覧表示をページネーション対応する

所有書籍検索結果表示をページネーション対応する

やったこと

現状を確認し対処を検討する

 

実施内容 

対処内容を確認する

index画面表示を確認する

まずは所有書籍の一覧表示画面から確認します。

[変更前]

# ~/app/Http/Controllers/PropertyController.php

public function index(){
 $user = Auth::user();
 $property = Property::userGetBook();
 return view('property.index',['user'=>$user, 'books'=>$property]);
}

propertyに関してはindexのリスト表示として出力するデータは「ログインしているユーザーが所持している本の一覧」です。このため、データ自体はスコープを作成して参照することでデータを取得していました。

 

スコープを確認する

スコープで記載していた内容も確認しておきます。 

[変更前]

# ~/app/Property.php

public function scopeUserGetBook(){
 $property = Property::where('user_id', Auth::user()->id)
  ->join('bookdata','bookdata.id','=','properties.bookdata_id')
  ->select('properties.id','title','picture','cover','freememo')
  ->get();
 return $property;
} 

スコープ上でログインユーザーが所有している書籍情報をwhereで取得していました。indexページヘッダにログインユーザーの所有書籍の数を表示させるのに使用していました。

 

ヘッダを確認する

ヘッダの所有書籍数は、ユーザーログイン後に右上に表示させています。

f:id:Fippiy:20190530135757p:plain

所有書籍数

複数箇所で同じデータ取得を利用しているためにスコープを利用する形として作成していました。

 

ヘッダ上に表示させている所有書籍数はプロバイダーを利用していました。 

# ~/app/Providers/UserServiceProvider.php

class UserServiceProvider extends ServiceProvider{
 public function boot() {
  View::composer(
   'components.user_nav', function($view) {
    $view->with([
     'name' => Auth::user()->name,
     'user_book_count'=> count(Property::userGetBook()),
    ]);
   }
  );
 }
}

ここで同じスコープを利用してデータ数を取得していました。

 

ページネーション対応する 

indexページのデータをページネーション対応させる 

リスト一覧表示はコンポーネントを利用しており、すでにページネーションに対応した設定になっています。

しかし所有書籍ページに表示させるデータはまだページネーション対応できていないので、対応できるようにします。

 

表示させるデータのページネーション対応はDBから取得したデータに->paginate()と記述を加えていました。 

# ~/app/Http/Controllers/PropertyController.php

public function index(){
 $user = Auth::user();
 $property = Property::userGetBook();
 return view('property.index',['user'=>$user, 'books'=>$property]);
}

しかし、indexには表示するデータの記述はありません。スコープを利用していました。

# ~/app/Property.php

public function scopeUserGetBook(){
 $property = Property::where('user_id', Auth::user()->id)
  ->join('bookdata','bookdata.id','=','properties.bookdata_id')
  ->select('properties.id','title','picture','cover','freememo')
  ->paginate(2);
 return $property;
} 

そこでスコープで取得しているPropertyデータに対してpaginate設定しました。これによって書籍情報の処理と同じく1ページ単位で指定した数だけ表示できるようになります。

f:id:Fippiy:20190530140740p:plain

所有書籍一覧ページネーション

コントローラー上のページネーション対応が完了さえすれば、ビュー表示はコンポーネント内で変更済みなので、ページネーション化した表示で出力されるようになります。

 

所有書籍件数表示が少なくなる

しかし、ここで問題が発生しました。

f:id:Fippiy:20190530141329p:plain

所有書籍表示

一見問題なく表示できているように見えます。

f:id:Fippiy:20190530141451p:plain

所有書籍数

しかし、画面右上に表示しているユーザーの総所有書籍数が2件になっています。テスト時の所有書籍は15件だったのですが、ページネーションの2件がそのまま表示されてしまっています。

このヘッダの件数はどこで取得しているか…というと、スコープで値を設定していました。

# ~/app/Providers/UserServiceProvider.php

public function boot(){
 View::composer(
  'components.user_nav', function($view) {
   $view->with([
    'name' => Auth::user()->name,
    'user_book_count'=> count(Property::userGetBook()),
   ]);
  }
 );
}

Propertyモデルのスコープを参照し、その結果のcountを表示するとしていました。

しかし、この呼び出し先のスコープをページネーション化したことでデータ取得がうまくできていないようです。

 

所有書籍件数表示を修正する

ページネーション化を維持したまま、データの総数だけを取得できれば今の問題を解決できそうです。

しかし、こちらは書籍情報の検索結果画面で件数を取得するときに実施していた方法でできそうです。total()を使用して件数を取得していました。

# ~/app/Providers/UserServiceProvider.php

public function boot(){
 View::composer(
  'components.user_nav', function($view) {
   $view->with([
    'name' => Auth::user()->name,
    'user_book_count'=> Property::userGetBook()->total(),
   ]);
  }
 );
}

スコープで取得したデータに対してtotalを使用することで総数を取得する記述に変更しました。件数が取得できるのでcountを利用する必要性がなくなったので削除しています。

f:id:Fippiy:20190530142255p:plain

所有書籍総数表示

これでページネーション2件表示でもヘッダ上は総数が表示されるようになりました。

  

書籍情報検索ページについてもページネーション対応する

indexページ対応に続いて検索ページも対応を実施しました。

こちらについては書籍情報検索ページで実施した内容とほぼ同一となるため詳しい内容は割愛します。

実施内容としてはフォームメソッドをpostからgetに変更し、検索ワードから取得するデータに関してページネーション化を実施しました。

 

テストを修正する

検索フォームからのデータ送信メソッドをpostからgetに変更しましたので、こちらも書籍情報のページ同様にテストについてもメソッドを変更することで、既存テストについては問題なく実施できることを確認しました。

 

以上で、所有書籍情報に関するページネーションと既存テストの修正については完了しました。

次は、新規に追加したページネーションに対してのテストを行っていきます。