niki12260714の日記

フリーランスのITエンジニアの呟き。

Ruby学習14日目:マイグレーション、form_tag、共通レイアウト、共通モジュール

今日は途中だらだらしつつも1日、rails学習してました。
Webアプリケーション開発でほぼ必須と思われる個所は手を付けられた感じ。

マイグレーション
・開発中にDBにカラム追加とか削除とかよくある話なので、マイグレーションはその変更をおこなうもの。
railsコマンドでどのモデルに対するマイグレーションか指定してファイルを生成、中身の書き換えをして、適用。
※自分はIDとDBのデータ作成日、更新日が自動作成と気づかなくてカラム作っていたので、これの削除と、テーブル名のスペル間違っていたので一旦テーブルをDropしてCreateをしました

【form_tag】
・ログイン画面で、メールアドレスとパスワードを入力し、POSTするのに使用。

f:id:niki12260714:20170917202402j:plain

※login/index.html.erbの中身
Userテーブルと結びつきが強いからform_forでも良かった気もするけど、modelから切り離すといform_forとの違いを体感したかったから。
そしてform_tagがPOSTした先のメソッドがこちら。

f:id:niki12260714:20170917202703j:plain

※login_controller.rb
ここのcheckメソッドがpostしたデータを使ってUserテーブルに対してwhere句を出してログインチェックをしています。
コメントアウトしているけど、ヒットするかどうか(.exists?)を変数flagにいれて、これがbooleanなのでifで分岐させて、成功しているならメイン機能のお知らせ画面に遷移。
false、つまりDBに該当するデータが無ければindexに戻って、その時に@msgにエラーメッセージ入れて返してます。
とりあえず、ログインできるかできないかの関門はできます。

ただ、ここの処理を調べているときに「Controllerにロジックを大量に記述するのは良くない」というのを見ました。
確かに、ビジネスロジックはmodelに書くべきですよね。
Controllerとmodelが分離できてなくて、保守するときに分かりにくくなる。
となると、form_tagではなくform_forを使いたくて、そのためにActiveModelという独自に生成するmodelがあるそうです。
次に似た処理を作る時は、ActiveModelを使ってみます。

【共通レイアウト】
メイン画面は上にメニューがあって、下にコンテンツを配置する画面構成です。
なので、「お知らせ」「アイテム登録・編集」「取り置き依頼一覧」「ブラックリスト編集」は共通のレイアウトを使用するため、テンプレートを用意。

f:id:niki12260714:20170917203932j:plain

↑ここの四角に囲まれているのと、「××さん」って表示されている部分がテンプレート。
このテンプレートを適用するのはcontroller単位でやってますけど、ある特定のメソッドは外す、ってのもできるみたい、便利!
ちなみに「××さん」は次の共通モジュールへ。

【共通モジュール】
メイン画面はログイン画面で認証されたユーザーしか使えないようにしたいので、王道のやり方、ログインチェックをかけた時にそのユーザーを一意に定めるidをsessionにいれておき、sessionの有る無しと、sessionから取得したidをDBに問い合わせてレコードが1件ならば画面表示、をします。
アプリケーション全体の共通処理を書く場所があるみたいですけど、ログイン画面は除外するし、取り置き依頼画面もログインしなくても大丈夫にしたいので、そういう場合はcontrollerの下にconcernsというフォルダがあるので、そこにいれておく。
modelの共通モジュールも、concernsがあるので、こちらに。

f:id:niki12260714:20170917204536j:plain

※共通モジュール:login_check.rb
なんか異常に苦労したのが、User.findで検索した結果を格納する@usrの中に入っているはずのdisplay_nameを取ってくるのが大変だった!
これ、Rubyのいいところでもあり難しいところでもあると感じたんですけど、変数の型を宣言しないので、どういう形で値が入っているのかが分からん……
なので、その中から持ってくるのはどうすればいいのかが分からない。
結局、自分がとった方法は、「render plain:」で変数の中身を一旦画面に吐き出して中身を見て推測し、地道にデバッグ
エラーになればエラーメッセージから推測もできるので、試行錯誤していました。
でもこれで分かったんで、今後は似たパターンでは応用できるかと。

さて次はScaffoldingでアイテム取り置き画面を作ります。
作ったテンプレートをいじって、自分好みにカスタマイズする方法の学習となります。