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

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

Laravel開発、ユーザー所有本を管理できるようにする【2】登録書籍とマイページのビューに統一性を持たせる

ユーザー所有の本情報を保存させて、ユーザー毎に管理できる設定をアプリに追加しています。

前回の記事はこちら。

fippiy.hatenablog.jp

ここまで作成して気づいたことがあります。

本情報管理ユーザー所有本管理という、主に2種類のページが存在しています。

ビューの構成はほぼ同じで、違うところはといえばページによってカラーを変更させることで変化させている程度。

当初は別のページなのでと思いスタイルシートを分けて考えていたのですが、クラス名とスタイルを統一できそうなので、ここで再整理して後々のメンテナンスも考えた使用にしたいと考え、見直すことにしました。

※そもそもそこから最初に設計すべきというご指摘はあるとは思いますが…。

 

 

今回の目的

本情報登録ページとマイページの構成を合わせ、スタイルシート設定を統合させる

※なお、本記事の都合上下記表現を利用する。

表現:ページ

Aページ:本情報管理ページ

Bページ:ユーザー所有本管理ページ

なぜやるか

ほぼ同じページであるにもかかわらず、別のクラス名とスタイルシートを用意していることに無駄を感じた為、統一させることでビューやレイアウトを再利用できるようにさせたい

やりたいこと

同じビューを使用し、クラス名を統一する

同じスタイルシートを使用し、統一する

ページ毎に設定する個別スタイルを設定する

やったこと

ページ構成について再考する

ページ構成をそろえる

同一コンポーネントで異なる配列からデータを取り出す

各ページ毎の設定を適用させる 

 

実施内容

ページ構成を考え直す

初期作成ページでスタイルを一本化

当初作成を始めた段階では「個別にページを作成=スタイルも個別」という考え方をしていました。

しかし、Aページを作成していく上で、ベースとなるスタイルは同じであるため、スタイルシートは一つにまとめるとメンテナンス性が上がると考え、クラス名を統一してページスタイルは1ファイルとして作成しました。

 

ビューも一本化させることを検討

そして、Bページ作成に移ったわけですが、作成するうちにAページと同じビュー構成で色だけ異なるといったスタイルになってきました。

※初期構想では全く別の表示を検討していたのですが、結果として同じ構成で作っていました。

同じスタイルであれば、同じコードを参照することで結果としてコード量も減り、なにより楽に作れそうと思いました。

そこで、Bページ用に作成していたビューファイルは削除し、作成済みのAページのクラスやスタイルを利用してBページを再構成することにしました。

------------------------------------

既存ビューページを再利用する

現状作成ページの差を確認する

現状作成済みのページを再度確認することからしました。

なんとなく気づいたでなく、しっかり見直して問題点を整理してから直して行くためです。

AページとBページの表示からみてみました。

# Aページのindex.blade.php

f:id:Fippiy:20190409133629p:plain

書籍情報管理

# Bページのindex.blade.php

f:id:Fippiy:20190409133648p:plain

書籍所有管理

Bページではユーザー情報を左側に表示させるような仕様を考えていましたが、他は色が違うのみで、構成はほぼ一緒です。

 

各ページのコードはこちらです。

# A[左:book/index.blade.php]  B[右:user/index.blade.php]

f:id:Fippiy:20190409132522p:plain

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]

f:id:Fippiy:20190409183929p:plain

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で設定しています。

 

そこで、条件分岐にコントローラー名を使用できないかやってみました。

f:id:Fippiy:20190409140230p:plain

ルート情報取得

以前パンくずリストを作成しているときにルート情報を取得する方法がありました。

ここでこの情報を利用しようと考えました。

 

参考にしていたサイト情報にもあった3つの記述方法を試して結果を再度確認してみました。表示確認の為、ビューファイルにPHPコードを直接いれています。

なお、一つ目のRoute::current()についてはprint_rしようとしてもエラーとなりましたので、ブレークポイントを設定してデバッグ中に中身を確認する手法を使いました。

ビュー表示

f:id:Fippiy:20190409140519p:plain

ルート情報表示

デバッグした$test変数の中身

f:id:Fippiy:20190409140536p:plain

Route::current()

ビュー表示にあるuser.indexというルート表示を利用すれば、目的であるAページとBページの分岐ができそうです。

しかし、デバッグ表示のなかに+uri:"user"とあるのでこれを利用することも出来そうです。

f:id:Fippiy:20190409140908p:plain

ルート情報取得2

f:id:Fippiy:20190409141001p:plain

ルート情報表示2

userのみが取得できました。

こちらで処理分岐ができそうです。

 

コントローラー名で条件分岐してみる

データを取り出すための方法をおさらいします。

AページはBookdataテーブルを参照し、$book->titleで取り出し

BページはPropertyテーブルを参照し、Bookdataをリレーション、$book->bookdata->titleとすることでデータを取り出すといった内容でした。

 

ここに条件分岐を利用して一つのコンポーネントでどちらにも対応させようとしています。 

まず、設定してみました。

f:id:Fippiy:20190409152304p:plain

PHPで一手間入れる

Bページの場合のみ$book->bookdataの処理を強制的にいれることで最終的に$book->title等でデータが出せるようにしてみました。

これでビューに表示はできました。

しかし、ビューファイル内にPHPコードが突然でてくるのもあまり良いようには思えません。

可読性もよくないと考え、他の方法を考えることにしました。

 

レコードの取り出し方を変更する

DB情報取得から考える

ビューに記述するコードを統一したままにするのであれば、とりだすデータを合わせてやればどうか?と思い、DB情報の取り出し方法を検討することにしました。

 

モデルのスコープ設定を作成する

DB情報取得について、Laravel学習の初めに使用していた本の中で登場したスコープによるデータ取得というものがありました。

さらにこちらを参考にさせて頂きました、ありがとうございます。

 

qiita.com

こちらを元に、データレコードをJOINによる結合によって取得すれば$book->titleで出力できそうと思いましたので、この方法で実施します。

------------------------

スコープを新たに作成してデータの取り出し設定をいれます。

# ~/app/User.php

f:id:Fippiy:20190409152858p:plain

モデル・スコープ

モデルでJOINによる結合をしてpropertiesテーブルとbookdataテーブルを結合した物を取得。

 

コントローラー側でスコープを呼び出す形に修正。 

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

f:id:Fippiy:20190409152759p:plain

コントローラ

修正した状態でブレークポイントを設定し、データが取得できているか確認します。

テーブル情報取得の確認

f:id:Fippiy:20190409183019p:plain

$property情報


 

結合したレコードが表示されました。

コンポーネントでの記述も$book->titleの記述で統一できたので、これでAページ、Bページ双方のページにそのまま適用できそうです。

 

ところで、この状態だと結局リレーション設定はしたもののテーブル結合でまとめて取得しているのでリレーションが活かせてないと思いました。

他にもいい手法はあるかもしれませんが、ほしいデータ取得できており、データ表示手順が統一できた状態ですので、今回のバックエンド処理はこれで進めます。

 

 

画面表示を確認する

実際にビュー表示できるか確認していきます。 

まずは複数のレコードが正常に表示されることの確認です。

Aページと同じコンポーネントを使用していますが、念のためBページでの出力を確認します。

Bページ用の登録ページはまだ作成していないので、DBに直接レコードを追加。

f:id:Fippiy:20190409184549p:plain

データレコード追加

ビュー表示確認。

f:id:Fippiy:20190409184618p:plain

ビュー確認

複数レコード表示を確認しました。

 

ユーザー毎のデータを表示させる 

Bページはログインユーザー自身の所有している本を表示させるページです。

しかし、現状はユーザーによるデータを選別せず全データが出力されている状態です。

そこで、ログインユーザーに限定する条件を追加します。

以下のサイトを参考にさせて頂きました、ありがとうございます。

blog.capilano-fw.comqiita.com

スコープで設定したテーブル参照コードにwhere条件を追加します。

 

f:id:Fippiy:20190409190047p:plain

ユーザー毎情報取得コードへ変更

テーブルからログインユーザidを取得し、そのユーザーが登録した情報のみを出力するといった形に変更しました。

これで表示を確認します。

f:id:Fippiy:20190409184618p:plain

ユーザー所有本情報のみ表示

表示はできました。

しかし、現状ひとりのユーザーが3つの本を登録しているだけなので、対象ユーザーだけの全データの設定ですが見た目の変化がありません。

 

ユーザーを追加して、ログインユーザーだけの情報が出ることを確認する必要が有ります。 

 

そこで、ユーザー新規追加して所有情報も追加して再確認。

# Userテーブル

f:id:Fippiy:20190409192418p:plain

ユーザー追加

id=2のユーザーを新規追加。

 

# Propertyテーブル

f:id:Fippiy:20190409192436p:plain

追加ユーザーの所有情報設定

新規ユーザーの所有データを追加。

 

新規ユーザーでログインしてビュー表示を確認。

 

f:id:Fippiy:20190409192515p:plain

ビュー表示

対象ユーザーだけの情報が表示されていることを確認しました。

 

 

ページを区別するための色分けをする

残っている問題を解決する

ビューファイルを見直している時に問題点として掲げていたのですが、AページとBページは明確にわかるように色を変えていました。

Aページメニュー及びタイトルは青色

Bページメニュー及びタイトルはピンク色

という整理になっています。

ビューに表示するデータの修正は完了したので、今度は色分けについて修正していきます。

 

スタイルシート上のメニューなどに直接backgroundとして色設定をしていたので、Aページのビューとスタイルシートを適用すると、全てのページが青色になっている…というのが現状です。

 

ここから色設定の方法を変更し、各ページ毎に対象の色が適用されるようにしていきます。

 

ビュー毎に適用する色を設定する1

初めにやったことは、ページ毎の色設定スタイルシートを作成し、変数に値をいれてみました。

scssでは変数が扱えるので、これを使ってページにあったスタイルシート設定を読み込む…という作戦だったのですが失敗しました。

 

scssでは変数が扱えるが、実際に参照しているファイルはcssであり、別ファイルで作成した変数は扱えませんでした。なにか別のやり方でいい方法あるかもしれませんが。

 

同一のscssファイル内であれば変数は受け渡せるという所までは確認しましたが、クラス名を同一にして必要な設定を読み込むのは難しそうでした。

 

ビュー毎に適用する色を設定する2

作戦を変更することにしました。

各ページ用の色設定用クラスを作成して個別に適用するという方法です。

同一コンポーネントを使用しているという点で、内部で個別のクラスを設定するのが問題になりそうだったのですが、現状のページではコンポーネント内で個別に色をつけていないので、この方法にしました。

# ~/public/scss/whole.blade.php

f:id:Fippiy:20190410125829p:plain

色設定クラス

色設定専用クラスを作成し、各ページでこのクラスを追加しました。

 

AページとBページのレイアウトを共通化はこれで完了です。

一つのベースとなるレイアウトで両方のページを表示させることができます。

ビュー構成のさらなる見直し

しかしここで、メニューリストの構成について問題が残っている事が分かりました。

以前見直す工程があったのですが、ここで改めて気づいたので修正します。

こちらについては記事が長くなっていたので一旦ここで切って、次で書くことにします。