Laravel開発、ユーザー所有本を管理できるようにする【2】登録書籍とマイページのビューに統一性を持たせる
ユーザー所有の本情報を保存させて、ユーザー毎に管理できる設定をアプリに追加しています。
前回の記事はこちら。
ここまで作成して気づいたことがあります。
本情報管理とユーザー所有本管理という、主に2種類のページが存在しています。
ビューの構成はほぼ同じで、違うところはといえばページによってカラーを変更させることで変化させている程度。
当初は別のページなのでと思いスタイルシートを分けて考えていたのですが、クラス名とスタイルを統一できそうなので、ここで再整理して後々のメンテナンスも考えた使用にしたいと考え、見直すことにしました。
※そもそもそこから最初に設計すべきというご指摘はあるとは思いますが…。
- 今回の目的
- 実施内容
今回の目的
本情報登録ページとマイページの構成を合わせ、スタイルシート設定を統合させる
※なお、本記事の都合上下記表現を利用する。
表現:ページ
Aページ:本情報管理ページ
Bページ:ユーザー所有本管理ページ
なぜやるか
ほぼ同じページであるにもかかわらず、別のクラス名とスタイルシートを用意していることに無駄を感じた為、統一させることでビューやレイアウトを再利用できるようにさせたい
やりたいこと
同じビューを使用し、クラス名を統一する
同じスタイルシートを使用し、統一する
ページ毎に設定する個別スタイルを設定する
やったこと
ページ構成について再考する
ページ構成をそろえる
同一コンポーネントで異なる配列からデータを取り出す
各ページ毎の設定を適用させる
実施内容
ページ構成を考え直す
初期作成ページでスタイルを一本化
当初作成を始めた段階では「個別にページを作成=スタイルも個別」という考え方をしていました。
しかし、Aページを作成していく上で、ベースとなるスタイルは同じであるため、スタイルシートは一つにまとめるとメンテナンス性が上がると考え、クラス名を統一してページスタイルは1ファイルとして作成しました。
ビューも一本化させることを検討
そして、Bページ作成に移ったわけですが、作成するうちにAページと同じビュー構成で色だけ異なるといったスタイルになってきました。
※初期構想では全く別の表示を検討していたのですが、結果として同じ構成で作っていました。
同じスタイルであれば、同じコードを参照することで結果としてコード量も減り、なにより楽に作れそうと思いました。
そこで、Bページ用に作成していたビューファイルは削除し、作成済みのAページのクラスやスタイルを利用してBページを再構成することにしました。
------------------------------------
既存ビューページを再利用する
現状作成ページの差を確認する
現状作成済みのページを再度確認することからしました。
なんとなく気づいたでなく、しっかり見直して問題点を整理してから直して行くためです。
AページとBページの表示からみてみました。
# Aページのindex.blade.php
# Bページのindex.blade.php
Bページではユーザー情報を左側に表示させるような仕様を考えていましたが、他は色が違うのみで、構成はほぼ一緒です。
各ページのコードはこちらです。
# A[左:book/index.blade.php] B[右:user/index.blade.php]
AページをベースにBページを作成していたので、同じコードになるのはまぁ当然といわれればそうだったんですが…。
Aページでは25行目で本の一覧表示をコンポーネントとして呼び出す設定としています。こちらは前回の記事で作成した内容です。
Bページも構成がほぼ同じである為、同じコンポーネントを扱おう…そう思ったわけですが、ここでそもそもページ全体の構成が同じであれば、全部同じ物をつかえば…という考えになりました。
2つのページで大きく異なるのはクラス名です。繰り返しになりますが、元々は全く別ページと考えていたのでクラス名も別で個別作成するものと考えていました。
同一構成に変更する
Bページのindex.blade.phpをまずAページ構成に変更して正常な表示にすることから始めました。
Bページではユーザー名の表示が追加されていましたが、ここは一端Aページに全部合わせることとし、ユーザー名表示は一端削除しました。
まず、「HTMLタグ・クラス名・books_listコンポーネント」をAページとあわせます。
B[user/index.blade.php]
ほぼ一緒です。タイトル名・ページメニューが違うくらい…。
ここまでで、user/index.blade.phpについてはコードを置き換えて表示できるようになりました。
違いとしては、1.ユーザー名表示がなくなったこと・2.色設定がAページ仕様の為、Bページとしての色表示でなくなっている点でしょうか。
1については表示方法そのものを後で再検討して場所を変えようと思っています。
2に関しては本工程で後から変更します。まず先にページ構成統一を先にしてしまいます。
ビュー表示するデータを取り出す
同じコンポーネントでページ毎のデータを出力したい
index.blade.phpでDBから表示させるデータはBookdataテーブルのレコードです。
Aページでは$book->title,$ book->detailといった値の取り出し方をしています。
Bページはどうか?
前回の記事でリレーション設定を実施したのでデータはとりだせますが
本所有情報はPropertiesテーブルのレコードです。
このまま取り出すには$property->bookdata->$titleとなり、Aページとは異なる記述となります。
表示ページを個別に作成していれば、各々のページで上記の記述をすれば問題ありません。
しかし、先程構成を同じにしました。
データを取り出す場所はbooks_listという名前のコンポーネント内に記述しています。
AページもBページも同じコンポーネントを参照しているのでなにか工夫がいります。
そこでコンポーネント内で条件分岐をする方法を考えてみました。
ビューで表示する値を条件分岐するキーを見つける
※この方法は結果として使わず、次のDBからのデータ出力方法を検討した手順を使用しています。
AページとBページで明らかな違いがあれば、それを条件分岐させればページ毎の設定ができそうです。
となれば明らかな違いはなにか?データを呼び出しているコントローラーが違います。
AページはBookController,BページはUserControllerで設定しています。
そこで、条件分岐にコントローラー名を使用できないかやってみました。
以前パンくずリストを作成しているときにルート情報を取得する方法がありました。
ここでこの情報を利用しようと考えました。
参考にしていたサイト情報にもあった3つの記述方法を試して結果を再度確認してみました。表示確認の為、ビューファイルにPHPコードを直接いれています。
なお、一つ目のRoute::current()についてはprint_rしようとしてもエラーとなりましたので、ブレークポイントを設定してデバッグ中に中身を確認する手法を使いました。
ビュー表示
デバッグした$test変数の中身
ビュー表示にあるuser.indexというルート表示を利用すれば、目的であるAページとBページの分岐ができそうです。
しかし、デバッグ表示のなかに+uri:"user"とあるのでこれを利用することも出来そうです。
userのみが取得できました。
こちらで処理分岐ができそうです。
コントローラー名で条件分岐してみる
データを取り出すための方法をおさらいします。
AページはBookdataテーブルを参照し、$book->titleで取り出し
BページはPropertyテーブルを参照し、Bookdataをリレーション、$book->bookdata->titleとすることでデータを取り出すといった内容でした。
ここに条件分岐を利用して一つのコンポーネントでどちらにも対応させようとしています。
まず、設定してみました。
Bページの場合のみ$book->bookdataの処理を強制的にいれることで最終的に$book->title等でデータが出せるようにしてみました。
これでビューに表示はできました。
しかし、ビューファイル内にPHPコードが突然でてくるのもあまり良いようには思えません。
可読性もよくないと考え、他の方法を考えることにしました。
レコードの取り出し方を変更する
DB情報取得から考える
ビューに記述するコードを統一したままにするのであれば、とりだすデータを合わせてやればどうか?と思い、DB情報の取り出し方法を検討することにしました。
モデルのスコープ設定を作成する
DB情報取得について、Laravel学習の初めに使用していた本の中で登場したスコープによるデータ取得というものがありました。
さらにこちらを参考にさせて頂きました、ありがとうございます。
こちらを元に、データレコードをJOINによる結合によって取得すれば$book->titleで出力できそうと思いましたので、この方法で実施します。
------------------------
スコープを新たに作成してデータの取り出し設定をいれます。
# ~/app/User.php
モデルでJOINによる結合をしてpropertiesテーブルとbookdataテーブルを結合した物を取得。
コントローラー側でスコープを呼び出す形に修正。
# ~/app/Http/Controllers/UserController.php
修正した状態でブレークポイントを設定し、データが取得できているか確認します。
テーブル情報取得の確認
結合したレコードが表示されました。
コンポーネントでの記述も$book->titleの記述で統一できたので、これでAページ、Bページ双方のページにそのまま適用できそうです。
ところで、この状態だと結局リレーション設定はしたもののテーブル結合でまとめて取得しているのでリレーションが活かせてないと思いました。
他にもいい手法はあるかもしれませんが、ほしいデータ取得できており、データ表示手順が統一できた状態ですので、今回のバックエンド処理はこれで進めます。
画面表示を確認する
実際にビュー表示できるか確認していきます。
まずは複数のレコードが正常に表示されることの確認です。
Aページと同じコンポーネントを使用していますが、念のためBページでの出力を確認します。
Bページ用の登録ページはまだ作成していないので、DBに直接レコードを追加。
ビュー表示確認。
複数レコード表示を確認しました。
ユーザー毎のデータを表示させる
Bページはログインユーザー自身の所有している本を表示させるページです。
しかし、現状はユーザーによるデータを選別せず全データが出力されている状態です。
そこで、ログインユーザーに限定する条件を追加します。
以下のサイトを参考にさせて頂きました、ありがとうございます。
スコープで設定したテーブル参照コードにwhere条件を追加します。
テーブルからログインユーザidを取得し、そのユーザーが登録した情報のみを出力するといった形に変更しました。
これで表示を確認します。
表示はできました。
しかし、現状ひとりのユーザーが3つの本を登録しているだけなので、対象ユーザーだけの全データの設定ですが見た目の変化がありません。
ユーザーを追加して、ログインユーザーだけの情報が出ることを確認する必要が有ります。
そこで、ユーザー新規追加して所有情報も追加して再確認。
# Userテーブル
id=2のユーザーを新規追加。
# Propertyテーブル
新規ユーザーの所有データを追加。
新規ユーザーでログインしてビュー表示を確認。
対象ユーザーだけの情報が表示されていることを確認しました。
ページを区別するための色分けをする
残っている問題を解決する
ビューファイルを見直している時に問題点として掲げていたのですが、AページとBページは明確にわかるように色を変えていました。
Aページメニュー及びタイトルは青色
Bページメニュー及びタイトルはピンク色
という整理になっています。
ビューに表示するデータの修正は完了したので、今度は色分けについて修正していきます。
スタイルシート上のメニューなどに直接backgroundとして色設定をしていたので、Aページのビューとスタイルシートを適用すると、全てのページが青色になっている…というのが現状です。
ここから色設定の方法を変更し、各ページ毎に対象の色が適用されるようにしていきます。
ビュー毎に適用する色を設定する1
初めにやったことは、ページ毎の色設定スタイルシートを作成し、変数に値をいれてみました。
scssでは変数が扱えるので、これを使ってページにあったスタイルシート設定を読み込む…という作戦だったのですが失敗しました。
scssでは変数が扱えるが、実際に参照しているファイルはcssであり、別ファイルで作成した変数は扱えませんでした。なにか別のやり方でいい方法あるかもしれませんが。
同一のscssファイル内であれば変数は受け渡せるという所までは確認しましたが、クラス名を同一にして必要な設定を読み込むのは難しそうでした。
ビュー毎に適用する色を設定する2
作戦を変更することにしました。
各ページ用の色設定用クラスを作成して個別に適用するという方法です。
同一コンポーネントを使用しているという点で、内部で個別のクラスを設定するのが問題になりそうだったのですが、現状のページではコンポーネント内で個別に色をつけていないので、この方法にしました。
# ~/public/scss/whole.blade.php
色設定専用クラスを作成し、各ページでこのクラスを追加しました。
AページとBページのレイアウトを共通化はこれで完了です。
一つのベースとなるレイアウトで両方のページを表示させることができます。
ビュー構成のさらなる見直し
しかしここで、メニューリストの構成について問題が残っている事が分かりました。
以前見直す工程があったのですが、ここで改めて気づいたので修正します。
こちらについては記事が長くなっていたので一旦ここで切って、次で書くことにします。