# インターンシップ開発体験:別紙 v3.5 ## railsでのページ追加 画面ツアーの最後で、「ローン」のメニューが以下のようなエラーとなってしまいましたね。 これを対処してみましょう。 ![image](https://hackmd.io/_uploads/rJiR62jo0.png) 先ずはエラーメッセージの意味を確認し、素直にそれに対処してみましょう。 RoutingErrorであり、No route matchesなので、[GET] "/loan/new"をしようとしたけれど、ルーティング情報として一致しなかった。ということを教えてくれているようです。 画面の後半は、どうやらrailsルーティング情報が表示されているようですね。 確かに、「loan」で画面内の検索をしてみても見つかりません。 railsルーティング情報は以下のファイルを確認してみましょう。 config/routes.rb ```ruby Rails.application.routes.draw do get "/", to: "users#top" get "/top", to: "users#top" post "/login", to: "users#login" get "/logoff", to: "users#logoff" get "/users/new", to: "users#new" post "/users", to: "users#create" get "/users/kekka/:user_id", to: "users#kekka" get "/mypage", to: "users#mypage" get "/kouza", to: "users#kouza" get "/meisai/:kouza_id", to: "meisai#index" get "/error/:message", to: "error#show" get "/futsu_yokin/new", to: "futsu_yokin#new" post "/futsu_yokin", to: "futsu_yokin#create" get "/futsu_yokin/kekka/:kouza_id", to: "futsu_yokin#kekka" get "/furikomi/select_moto_kouza", to: "furikomi#select_moto_kouza" post "/furikomi/set_moto_kouza", to: "furikomi#set_moto_kouza" get "/furikomi/select_bank", to: "furikomi#select_bank" post "/furikomi/set_bank", to: "furikomi#set_bank" get "/furikomi/select_shiten", to: "furikomi#select_shiten" post "/furikomi/set_shiten", to: "furikomi#set_shiten" get "/furikomi/select_saki_kouza", to: "furikomi#select_saki_kouza" post "/furikomi/set_saki_kouza", to: "furikomi#set_saki_kouza" get "/furikomi/input_kingaku", to: "furikomi#input_kingaku" post "/furikomi/set_kingaku", to: "furikomi#set_kingaku" get "/furikomi/kakunin", to: "furikomi#kakunin" post "/furikomi/jikkou", to: "furikomi#jikkou" get "/furikomi/kekka", to: "furikomi#kekka" end ``` get ~~/new と言う記載は幾つか見えますね。 では試しに最後の行に、既存の記載を真似して、以下を追記して保存してみましょう。 get "/loan/new", to: "loan#new" 改めてトップページからローンメニューへ行こうとすると、、、 ![image](https://hackmd.io/_uploads/SJjp-6ioC.png) メッセージが変わりましたね! どうやら対処は効果ありそうです。 今度のメッセージは何でしょうか? Routing Errorなのは変わらずですが、二行目に変化があります。 uninitialized constant LoanController と言うことなので、どうやらローンのためのコントローラが見つからないようです。 ![image](https://hackmd.io/_uploads/ryNizaisA.png) 確かになさそうです。 では、一旦既存のコントローラをどれかコピーして、 LoanControllerという名前に変えて配置してみましょう。 newメソッドがあって、内容がシンプルな方が改変しやすそうなので、ここではFutsuYokinControllerをコピーしてみます。 エクスプローラで、対象ファイルをクリックして、Ctrl+C → Ctrl+Vをしてみましょう。 ![image](https://hackmd.io/_uploads/B1DoQ6oo0.png) 続いてF2(ファンクションキーの2)を押してみましょう。ファイル名を編集できるはずです。命名は規則に従っている感じがしますので、loan_controller.rb としてみましょう。 次は内容を更新してみましょう。 一行目のクラス名は「LoanController」に変更します。 メソッドはいくつかあるようですが、先ずは必要なnewメソッド以外は消してしまいましょう。 ![image](https://hackmd.io/_uploads/HJSLITjsA.png) このままではメソッドの内容が良くないと思うので、どういった動作になってほしいかを考えてみます。 取り敢えずは、赤と黒のいかにもエラー画面、というページに遷移してしまうのではなく、内容は空でも良いので、一旦自分の作成したページに遷移してほしいかなと思います。そうすると、今見えている処理は、、、 ```ruby=3 user = User.find(session[:user_id]) ``` どうやらDBにselect文を発行しているようです。 今は取り敢えずは、DBには用はないので、ここは消して良さそうです。 どこか他のコントローラで、ページ遷移を実現している箇所はないのでしょうか? コピー元としたfutsu_yokin_controller.rbの29行目はどうでしょうか? ```ruby=29 redirect_to "/futsu_yokin/kekka/#{kouza.id}" ``` どうやらredirect_toという記載で、任意のページに遷移できそうですね。 あるいは、users_controller.rbの10行目はどうでしょうか? ```ruby=3 class UsersController < ApplicationController # GET /top def top @login_id = session[:login_id] @password = session[:password] # /app/views/users/top.html.erb render :top end ``` render :topと言う記載で、/app/views/users/top.html.erbを呼び出せているようです。erbは、HTMLなどの文章の中にRubyスクリプトを埋め込むためのライブラリでしたね。 どちらでも良さそうですが、ここでは取り敢えず記述が簡単そうなrenderを試してみましょう。 書き換える必要がありそうな箇所を確認してみると、、、 /app/views/users/top.html.erb → ”views”まではそのままで良さそうです。usersは、小文字で複数形に見えるので、loansとしておきます。top.html.erbは、ルーティング情報として先ほどget "/loan/new", to: "loan#new"と書いたので、new.html.erbとしてみましょう。 render :top → :newとすれば良さそうです。 ![image](https://hackmd.io/_uploads/Hyx_-najiA.png) 一旦この状態で、動作の変化を確認してみましょう。 ![image](https://hackmd.io/_uploads/H1K_26ioA.png) SyntaxError、つまり、何か書き方を間違えているようです。良く見ると、クラスのendが足りないですね。要らないところを消した際に、消しすぎたみたいです。慌てずエラーメッセージの内容を確認して対処していきましょう。 今度こそ大丈夫でしょうか? ![image](https://hackmd.io/_uploads/S1hVpTosR.png) 良さそうです。 Template is missingとなっており、 Missing template loan/new, application/newということなので、ルーティングはできたが、その先のテンプレートがない、というメッセージのようです。 確かにまだ、new.html.erbを配置してなかったですね。 ![image](https://hackmd.io/_uploads/H1UVATsjR.png) コントローラと同じ要領で、ビューも何かをコピーして作成してみましょう。 先ずはフォルダが必要そうなので、viewsを右クリックして、New Folder..をクリックします。 ![image](https://hackmd.io/_uploads/Bk0e1RssA.png) フォルダ名は先ほどloansとしてみる検討をしたのでそのようにしておきます。 では何かerbファイルをloansフォルダにコピーしてみましょう。 取り敢えずシンプルで良いので、ここではぱっと見で記述の少ないapp/views/users/logoff.html.erbをコピーしてみます。 ![image](https://hackmd.io/_uploads/H1UigRiiC.png) ファイル名を変更します。new.html.erbですね。 取り敢えず配置してみたので、これで動きを確認してみましょう。 フォルダ追加の場合、railsサーバの再起動が必要ということなので、ターミナルでrailsサーバを動作させている画面に対して、Ctrl+Cでサーバの停止、再びrails sでサーバの起動を行いましょう。 ![image](https://hackmd.io/_uploads/S1DXzAosC.png) メッセージに変化がないようです。 命名規則を確認せずに、フォルダ名を小文字の複数形としたところ振り返ってみます。周りを見ると、メニューである振込や明細は小文字の単数形ですね。 フォルダの命名を変更してみましょう。 ![image](https://hackmd.io/_uploads/BkAAERss0.png) 出来ましたね! 取り敢えずこれで、新しい画面を追加することができました。 これまでを振り返ってみると、 1. ルーティング情報を追加 2. 対応するコントローラを追加 3. 対応するビューを追加 以上の3点で、任意のページの追加ができるということが分かりました。 railsの動きとして、ルーティング→コントローラ→ビューという流れがあることを意識できたかなと思います。 また、railsは、レールという名前のとおりで、レールに沿って進めば楽だよ、という感じのようで、命名規則が決まっているようです。そこはrailsの公式ドキュメントを確認していく必要がありそうなことも分かりました。 現状ではまだ、コントローラで何も業務的な処理を実装していないため、これではお客様がローンの取引を行うことができません。 でももう特に怖いことはなさそうですね。 新しいページを追加することはできるようになりました。 DBにアクセスして、情報の取得や追加、更新、削除はできるはずです。 機能追加の要件、設計を行い、実装をしていってみてください。 ## 規模の把握 皆さんは今回の開発体験のプロジェクト規模は意識されていますでしょうか? 例えば今回のプロジェクトディレクトリ配下は以下のような拡張子のファイルで構成されているようです。 ここではbashというLinuxのシェルコマンド一行で集計をしています。 ```bash moneta@localpc:~/project/rails/moneta3.5$ echo " count suffix" ; find . -type d -name '.git' -prune -o -type f -exec basename {} \; | grep -o '\.[^.]*$' | sort | uniq -c count suffix 276 .cache 3 .css 1 .dev 21 .erb 1 .gitignore 3 .html 1 .ico 7 .js 1 .json 17 .keep 1 .lock 2 .log 1 .md 1 .pdf 1 .pid 6 .png 56 .rb 1 .ru 1 .sqlite3 1 .tool-versions 3 .txt 7 .yml moneta@localpc:~/project/rails/moneta3.5$ ``` 今回はrailsアプリですので、画面の定義であるビュー以外の、業務ロジックと呼べるプログラムの開発規模は以下で確認可能です。 ```bash moneta@localpc:~/project/rails/moneta3.5$ rake stats +----------------------+--------+--------+---------+---------+-----+-------+ | Name | Lines | LOC | Classes | Methods | M/C | LOC/M | +----------------------+--------+--------+---------+---------+-----+-------+ | Controllers | 336 | 261 | 7 | 29 | 4 | 7 | | Helpers | 12 | 12 | 0 | 0 | 0 | 0 | | Jobs | 7 | 2 | 1 | 0 | 0 | 0 | | Models | 18 | 14 | 4 | 0 | 0 | 0 | | Mailers | 4 | 4 | 1 | 0 | 0 | 0 | | Channels | 8 | 8 | 2 | 0 | 0 | 0 | | Views | 482 | 407 | 0 | 0 | 0 | 0 | | Stylesheets | 28 | 25 | 0 | 0 | 0 | 0 | | JavaScript | 30 | 16 | 0 | 0 | 0 | 0 | | Libraries | 0 | 0 | 0 | 0 | 0 | 0 | | Controller tests | 140 | 115 | 5 | 25 | 5 | 2 | | Helper tests | 0 | 0 | 0 | 0 | 0 | 0 | | Model tests | 35 | 15 | 5 | 0 | 0 | 0 | | Mailer tests | 0 | 0 | 0 | 0 | 0 | 0 | | Channel tests | 11 | 3 | 1 | 0 | 0 | 0 | | Integration tests | 0 | 0 | 0 | 0 | 0 | 0 | | System tests | 0 | 0 | 0 | 0 | 0 | 0 | +----------------------+--------+--------+---------+---------+-----+-------+ | Total | 1111 | 882 | 26 | 54 | 2 | 14 | +----------------------+--------+--------+---------+---------+-----+-------+ Code LOC: 749 Test LOC: 133 Code to Test Ratio: 1:0.2 ``` ビューの規模は以下で確認可能です。 ```bash moneta@localpc:~/project/rails/moneta3.5$ echo " count view steps" ; find ./app/views -name "*.erb" | xargs wc -l count view steps 4 ./app/views/error/show.html.erb 9 ./app/views/furikomi/input_kingaku.html.erb 50 ./app/views/furikomi/kakunin.html.erb 4 ./app/views/furikomi/kekka.html.erb 28 ./app/views/furikomi/select_bank.html.erb 29 ./app/views/furikomi/select_moto_kouza.html.erb 28 ./app/views/furikomi/select_saki_kouza.html.erb 23 ./app/views/furikomi/select_shiten.html.erb 23 ./app/views/futsu_yokin/kekka.html.erb 17 ./app/views/futsu_yokin/new.html.erb 46 ./app/views/layouts/application.html.erb 13 ./app/views/layouts/mailer.html.erb 1 ./app/views/layouts/mailer.text.erb 4 ./app/views/loan/new.html.erb 49 ./app/views/meisai/index.html.erb 26 ./app/views/users/kekka.html.erb 28 ./app/views/users/kouza.html.erb 4 ./app/views/users/logoff.html.erb 35 ./app/views/users/mypage.html.erb 29 ./app/views/users/new.html.erb 26 ./app/views/users/top.html.erb 476 total moneta@localpc:~/project/rails/moneta3.5$ ``` つまり、皆さんは1kstep規模の案件にて、試験工程に参画し、何件かのバグを摘出されました。そしてそれらの全てではなくとも何件かを修正し、プロジェクトの品質向上に貢献した、と言えるはずです。 数字が全てと言うことでなく、一つの指標として利用可能だ、ということをご紹介しておきます。 是非今後も、対象の規模を把握して、定量的な報告を心掛けてみましょう。 ## ソフトウェアテスト 歴史的にはもう50年以上、人類のソフトウェア開発が続いているということで、人間が作業する以上、そして複数の人間が協業する以上、世界中、古今東西、大体同じような問題が発生してきているようです。国際的にそういった品質担保の資格やガイドラインが複数あり、会社組織ごとにも独自の積み重ね、ノウハウがあるという状況です。 一つ、日本語で公開されている情報をご紹介しておきます。 https://jstqb.jp/dl/JSTQB-SyllabusFoundation_Version2018V31.J03.pdf 色々書いてありますが、「1.3 テストの 7 原則」は読んでおいても良いかと思います。また、言葉の定義ですが、エラーやバグといった言葉を「1.2.3 エラー、欠陥、および故障」で説明しています。 会社組織ごとの文化があるため、上記はあくまでも考え方の一つですが、エンタープライズでのソフトウェア開発は、作りっぱなしという訳には行かず、「作業ミスをするし意思疎通も色々なロスが起こる”人間”というリソースで、如何に品質を確保して、納期に間に合わせ、自分たちの利益も確保するか」という挑戦、ゲームという捉え方ができます。 また、テスト技法も「4 テスト技法」で代表的なものが紹介されています。例えば今回数値の入力を受け付ける項目があったと思いますが、境界値分析という手法が考えられたかも知れません。 伝えたいこととしては、今回の開発体験では試験不十分な(というか試験がされていないような)アプリを例としていますが、いざエンタープライズのソフトウェアを試験しようとする時は、担当者の思い付きのみで行動する訳ではない、試験には試験なりのアプローチがあるよ、ということです。 ## 状況の可視化 今回皆さんの作業状況の可視化に利用したアプローチを紹介いたします。 以下は1秒間に処理したhttpリクエストのランキングです。bashのコマンドを活用して、ログを集計しています。 ```bash moneta@monetasv:~$ echo " http access tps top 10" ; grep Started /home/moneta/project/rails/moneta3.5/log/development.log | cut -d " " -f 7,8 | uniq -c | sort -nr | head http access tps top 10 12 2024-08-28 01:25:49 8 2024-08-28 02:04:04 8 2024-08-28 01:53:10 8 2024-08-28 01:40:06 7 2024-08-28 02:16:04 7 2024-08-28 02:15:51 7 2024-08-28 02:11:54 7 2024-08-28 02:11:45 7 2024-08-28 02:11:25 7 2024-08-28 02:11:19 moneta@monetasv:~$ ``` 上記をちょっと改変すれば、日ごとのアクセス数になります。皆さんが如何に演習に真剣に取り組んでいただけたか分かりますね。 ```bash moneta@monetasv:~$ echo " http access top 10" ; grep Started /home/moneta/project/rails/moneta3.5/log/development.log | cut -d " " -f 7 | uniq -c | sort -nr | head http access top 10 5984 2024-08-28 210 2024-08-19 194 2024-08-20 175 2024-08-26 77 2024-08-27 61 2024-08-23 54 2024-08-14 41 2024-08-22 34 2024-08-25 29 2024-08-21 moneta@monetasv:~$ ``` 以下はアクセスしたページのランキングです。こちらも同じくbashのコマンドを活用して、ログを集計しています。 ```bash moneta@monetasv:~$ grep Processing /home/moneta/project/rails/moneta3.5/log/development.log | cut -d " " -f 3 | sort | uniq -c | sort -nr 940 UsersController#mypage 808 UsersController#top 492 UsersController#kouza 316 FurikomiController#select_shiten 314 FurikomiController#select_moto_kouza 291 UsersController#login 289 FurikomiController#select_bank 282 FurikomiController#select_saki_kouza 265 FurikomiController#kakunin 264 FurikomiController#input_kingaku 253 FurikomiController#set_shiten 242 MeisaiController#index 234 FurikomiController#set_bank 233 FurikomiController#set_moto_kouza 216 FurikomiController#set_kingaku 192 FurikomiController#jikkou 173 UsersController#new 171 FurikomiController#set_saki_kouza 164 FurikomiController#kekka 160 UsersController#logoff 133 FutsuYokinController#new 115 UsersController#create 93 UsersController#kekka 59 FutsuYokinController#kekka 57 FutsuYokinController#create 12 Rails::InfoController#routes 1 ActiveStorage::DiskController#show moneta@monetasv:~$ ``` このように専用のツールなどなくても、ちょっとしたシェルのコマンドの繋ぎ合わせで、ログから役に立ちそうな情報を集計、可視化することが可能です。プロジェクトによってOSはWindowsかも知れませんが、大体同じようなことはできるはずです。アプリケーション開発の中では、こうしたアプローチもできると便利ですよ、という紹介でした。 ## 可読性と冗長性、保守性のバランス プロジェクトディレクトリにREADME.mdがあることに気付いたでしょうか?是非一読してみてください。その中には以下のような記載があります。 - 初学者を想定し期間が短いことから、バッドプラクティスであってもコードの追いやすさ、理解しやすさを重視 - パーシャルによる画面や部品の共通化を使用しない - CSSファイルによるデザインの共通化は行わない 詰まり、可読性を追及し、冗長性は仕方ない、と判断したのですね。では保守性はどうだったでしょうか?対応いただいたバグの中に、特定の画面だけヘッダのボタン名がおかしい、という事象があったと思います。普通に考えたら、こういう箇所って全体に共通する内容だから、どこかに一つ部品として作成して、それを呼び出すようにすれば楽なのに、と思いませんか?改修する際も、あとどれだけ同じミスがあるか調査しなければならない、となりませんでしたか?自分の改修対象に抜け漏れがないことを、自信を持って説明できるでしょうか? 一般にはrailsの思想として「DRY」(Don’t Repeat Yourself)という、「すべての知識はシステム内において、単一、かつ明確な、そして信頼できる表現になっていなければならない」という感じの開発原則があったりします。今回まさに、同じこと実現しようとしているが、一部実装にミスがある、という感じに見えましたね。これは、DBで言えば更新時異状と言える状況で、「一事実一カ所」になっていないので、人間が改修する際に、同じことしている箇所を一緒に同じように改修しなければならない、という、バグの温床、保守性が悪いと言える状況に見えます。この辺は、案件規模、案件期間、システムライフサイクル、開発担当スキルなど、様々な要素を考慮して、案件ごとにマネージャーが判断していくこととなります。 ## マークダウンのすすめ このテキストはhackmdというサイトで公開されており、中身はマークダウンというルールに従って記載されています。 Ctrl+Uと押して、このページのソースを確認してみましょう。 「インターンシップ開発体験」と検索し、どういった書き方で、文字サイズの変化やコード部分と見栄えの調整など行っているか確認してみてください。HTMLの`<div>`などのタグを使っていない、普通の文章と、シャープやクオートなどの記号で構成されていることが分かると思います。これは、とても生産性高く文書の作成、共有ができる、ということになります。是非試してみてください。 以上