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

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

Laravel開発、ユーザー所有本を管理できるようにする【4】ユーザ所有本を登録する

ユーザー所有の本情報を管理するという工程のなかで、前回ビュー表示の修正をしていました。

fippiy.hatenablog.jp

ビューに関する問題点を解決させたので、今回の実装で一番肝心のユーザーが所有している本を登録する内容を実装します。

※今回より使用エディタを変更していますので、コード画面が変更されています。

 

今回の目的

ユーザーが所有している本を登録し管理できるようにする。登録の際には書籍情報として登録されている本を元に登録を実施する。

なぜやるか

所有情報DBを利用してユーザー自身が登録をし管理できる仕様を組み込むため

やりたいこと

登録用フォームを用意して、そこから登録をさせたい

本データを登録しているDBから、任意の本を選択して所有本として登録させたい

所有済みの本は重複登録できないようにしたい

やったこと

登録手順を確認する

登録するためのビューページを作成した

選択した本とユーザー情報を保存させた

登録した本を確認できるようにした

重複登録を回避した

全書籍登録時の処理を追加した 

 

実施内容

所有書籍を登録するビューを作成

登録手順を考える

現状のままではDBに直接書き込むしか手段がない為、ユーザーが書籍登録のビューから本を選択して登録するページが必要です。

まず、登録するためのページを準備します。

登録する為にはDBから本の選択と登録ボタンをおす必要があります。

他にも、DBからでなく新規に本も追加するなどいろんなパターンが考えられますが、

まずは登録されている本からひとつ選択して登録する手順として実装します。

 

既存ビューを元に所有書籍登録ページを作る

まず初めにユーザー所有本を登録するためのビューとコントローラーに表示ビュー設定を準備します。

# 書籍登録ビュー

f:id:Fippiy:20190413135744p:plain

ビュー作成

登録書籍から任意の本を選べるようにセレクトフォームを作成し、選択して登録ボタンを押す構成としました。

# 登録書籍ビュー(登録完了)

f:id:Fippiy:20190413135930p:plain

登録完了画面

登録完了後の表示です。

登録完了した旨のメッセージを表示し、登録内容を表示しました。

一時確認の為、登録したタイトル名を画面下部にまず表示させてみました。

 

コードは以下の内容となりました。

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

f:id:Fippiy:20190413141146p:plain

本情報登録

ユーザーが所有している本ということで、今回はUserControllerに作成しました。

所有書籍登録ページの表示、フォーム選択後のDB登録処理がこちらになります。

 

コードの内容としては、

画像登録の処理がない…以外は以前の書籍登録とさほど代わりはありません。

加えた処理としては、登録時に現在のユーザーidをあわせて登録しているくらいです。

ユーザーidを個別に取得して$formへ追加しています。

また、登録後に続けて次の本を登録できるように、Bookdata情報を再び取得するようにしています。

 

コンポーネントに値を引き渡す

# ~/resource/views/user/create.blade.php

左/変更前、右/変更後

f:id:Fippiy:20190413142917p:plain

視覚情報を増やして見やすくする

登録完了時にタイトル名のみを画面下部に表示していましたが、既存コンポーネントを利用して詳細情報をだすようにしました。

ここで前回の記事でコンポーネントに対して引数を指定することを書いていたのですが、試したところうまく動作してくれました。

具体的には、コンポーネント上では$book->title等の記述でデータを引き出していますが、$propertyはリレーションを組んでいるため、$property->bookdata->titleというデータ参照が必要です。

今回"book"に$property->bookdataと引き渡すことで、参照先の記述を統一させることにしました。

これで前々回の記事でデータをJOINしていた内容も修正できそうです。

すこし話がそれましたが、データを効率良く引き出せるようになったので、こちらで実装をすすめます。

 

書籍登録コントロールを充実させる

重複登録を回避する

現在の仕様は本情報として登録されているデータを全て呼び出し、その中から所有している本を選択するという形になっています。

このため、常に全ての本が選択肢にり、同じ本がいくつも登録できる状態です。

複数所持のケースもあるかもしれませんが、一つ登録を原則として重複登録を不可にします。

 

これを実現させる為に、全書籍情報から所有している本を除外するというデータ取得が必要になります。 

具体的には、このようなステップが必要と考えました。 

  1. Propertyから現在のユーザーの情報だけとりだす
  2. Bookdataから上記のデータを除外する

まずPropertyという登録済み書籍のidのみを取得しました、取得方法についてはこちらを参考にさせて頂きました、ありがとうございます。

laravel.hatenablog.com

これを元にコードをまずは書いてみました。

データ取得はモデル内にスコープとして記述しました。

# app/User.php

f:id:Fippiy:20190413151913p:plain

スコープ

未所持書籍として取得するためのスコープを用意し、まず所持済みの本情報から本のidのみを取得しています。

そこから次に、全書籍データから、先程取得したidを除外することで、未登録の情報を取得する…といった形にしています。

 

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

f:id:Fippiy:20190413151803p:plain

本情報登録画面コントローラー

 

先程作成したスコープを参照する方式に変更しました。

これで、ビュー表示時点で選択肢が未登録本のみになります。

 

 

全書籍登録済み時の処理

全書籍が登録されている場合に登録ボタンを押すことによるエラーを回避しておく必要があります。

バリデーションや登録する本がないといった処理が考えられますが、今回はそもそもフォームを表示させないという方法としました。

# create.blade.php

f:id:Fippiy:20190413153621p:plain

ビュー表示

未所持本のデータ数が0の時、つまりは全書籍を所持している時は、フォーム自体をださない設定としています。

 

以上で、リストからタイトルを選択する方式で書籍登録できるようになりました。

複数登録やUIにいろいろ変更を加えることでより便利になりそうですが、まず登録できるという状態になったので、一端登録処理としては完了です。

 

後は、登録した本に関しての検索や手放した際の削除等を実装していきます。 

fippiy.hatenablog.jp