パーフェクトRails輪読会 ver1
パーフェクトRails輪読会
8月23日 パーフェクトRails 1章
1-1-1 - プロジェクトを新規登録する際、git init で作業を記録する場を構築します。 - Ruby2.7とRails6.0の組み合わせは警告が発生する場合があります。
1-1-2
Rubygemsとは
RubyGemsは、Ruby言語用のパッケージ管理システムであり、ライブラリの配布用標準フォーマットを提供しています。gemを容易に管理できます。
$ rails _バージョン名_ -v
と入力するとインストールしているバージョンの中から任意のバージョンを指定できる
1-1-3
rakeタスク
実行したい内容をあらかじめ定義するもの。実行方法は時間指定でも手動でも関係ないです。(例:顔を洗う,歯を磨く,など) Linuxはmake == rubyはrake
rakeタスクの生成についての基本構文
desc 'rails, muzukashi' task 'rails' do puts 'rails muzukashi' end
desc・・・タスクの説明 task・・・タスク名称と実行内容
cronとwhenever
事前に定義したrakeタスクを時間という概念をもとに実行する機能のこと。 (例: 毎朝7:00に顔を洗う, 7:30に朝ご飯を食べるなど)
rakeコマンド
rakeタスクを実行するためのコマンド
1-1-4
bundleコマンドとは
gemパッケージの仕組みを利用してどのgemパッケージを使用してどのバージョンを使用しているのかを明示する仕組みです。
$ bundle exec
をつけるとGemfile.lock
に書かれているバージョンのgemが動きます。ディレクトリで定義しているバージョンがつかわれます。$ bin
と$ bundle exec
は同じです。($ bundle exec
は $ bin
の中に含まれるものというイメージです。)
bundlerでよく利用するサブコマンド
$ bundle install -> bundle iまたはbundleでも可 $ bundle update [ライブラリ名] -> バージョン更新 $ bundle list -> インストール済みのgemパッケージの一覧表示 $ bundle init -> Gemfileを生成。 $ bundle exec [コマンド名] -> Bundlerでインストール
$ bundle install
に--path vendor/bundle
つける??付けなくともいいと思います。→ bundlerを使っているから!!!(書くことで家の中にもめっちゃ鍵かけるイメージ)
1-2 Railsの思想
CoC(Convention over Configuration)
設定より規約という意味です。 規約に従うことで関心ごとがシンプルになり、本来注力すべきビジネスロジックへ集中できるようになります。
DRY(Don't Repeat Yourself)
同じ事を繰り返さないという思想です。情報の重複をなくし、一つのことは一箇所だけに記述します。 DRY原則を守る事によって変更が生じた際に何箇所もコードを修正する事がなくなり、メンテナンス性が高まります。
REST(Representational State Transfer)
URL web上の住所 URN web上の名前 URI web上の住所 + web上の名前
自動テスト
デフォルトはMinitest。基本はRSpecを使用します。
アーキテクチャ
アーキテクチャ(木造建築)>フレームワーク(家の建て方)>ライブラリ(工具箱)>コンポーネント(材料、道具、部品)
参考
bundle install --path vendor/bundle
について
https://qiita.com/jnchito/items/99b1dbea1767a5095d85
フレームワークとアーキテクチャの違い - Yahoo!知恵袋
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q14158287509
技術負債の内容について - Qiita
https://qiita.com/erukiti/items/9cc7850250268582dde7
URIについて
bundle execについて
https://qiita.com/d0ne1s/items/fa2dafcee02e963fe997
Rakeタスクについて
https://pleiades.io/help/ruby/rake.html
肉さんNotion
https://www.notion.so/rake-cron-9f0512dd664d45238780512a8c304979#f9e3c558cd2343408eec8ffb0551bf85
環境構築時の$ PATH を通すとは
プログラミングを本格的にスタートして5ヶ月目に入りましたさかもとです。
今回はdiscordで他の受講生の方がpathをとおしていないので環境構築ができなかったという話を耳にしました。私も今まで環境構築を何度か行ってきたのですがその現象に当たることはありませんでした。なので今回この話を聞いた時、pathって結局なんなの?なんで通すの?と疑問に思い調べてみたので復習の意味も込めてアウトプットしたいと思います。
rbenvって何?
ここから順に書いていこうと思います。
環境構築を行う時、事前にrubyのバージョンを指定し現環境で使用できるようインストールしていると思います。rbenvはそのrubyのバージョンを管理し適切にインストールできるようサポートするrubyバージョン管理ツールのことです。
pathとは
コマンドを検索するためのpathのことです
....???となりました。
一つ一つ紐解いていこうと思います。
コマンドとは
lsとかをターミナルで実行したことがあると思います。
このlsもコマンドコマンドの一つです。
ではpathを通すとは
このコマンド。今まではなんのけなしにターミナルで $ ls ~とうっていたと思います。しかしこれは正確な表現ではありません。
このlsというのはこのコマンドを定義しているファイルを辿ってそこに書かれているlsという役割のコマンドを拾ってきて実行しているというのが正しい解釈です。
では結局pathを通すとはなんなのか。
もしこのpathを通さないとlsを実行する際、どうしなくてはいけないか。ターミナルで echo $PATH を実行すると
このように出てくると思います。これは分解すると
/usr/local/opt/openssl@1.1/bin
このようになり各コマンドがどのファイルの中に保存されているかがわかるようになっています。pathを通さないと入力したコマンドがどこのファイルに保存されていてどこから引っ張ってくればいいのかわからず実行できなくなってしまうのです。
その状況を回避するために環境構築段階でpathをとおしlsと打っただけコマンドが実行できるようにするためにpathを通す必要があった訳です。
最後に
次回は環境変数とは?と設定方法についてまとめてみようと思います。
rails6にbootstrapのモーダルを実装した話
プログラミングを本格的にスタートして5ヶ月目に入りましたさかもとです。
今回はrails6に導入したbootstrapとjqueryを合わせてモーダルを表示した際に詰まってしまったので復習の意味も込めてアウトプットしたいと思います。
bootstrapのモーダルとは
こちらは添付したbootstrapの公式サンプル集をみていただければわかりやすいと思います。
ボタンを押すと画面に小さな画面が表示されます。
このようなものです。
ajaxとは
通常、同期処理にて画面全体を更新するものですがajaxを導入すると画面の一部分だけを非同期で更新します。
ajaxについては別記事で詳しく取り上げようと思いますのでそちらをご覧ください。
今回私が詰まってしまったのは以下のような状況です。
これは私がポートフォリオで実装しようとしている一部分なのですがコントローラーにデータを送った後に質問や回答欄を消しその後にモーダルが表示されると言う実装を行っています。
これの何に詰まってしまったのか。
それはbootstrapのサンプルではボタンを押すとすぐにモーダルを出現させる仕組みなのでjqueryなどを裏で動かしているとモーダルが表示されないと言う問題です。
思考
今回に限ってはエラー文などは発生しませんでした。
ただ、画面が暗くなるだけでモーダルが表示されないと言う情報しかありませんでした。
そこでjqueryでモーダルを表示させると言う内容を検索します。
するとおそらくそこまで多くの記事は出てこないと思うのですが下記添付記事が解決に導いてくれると思います。
BootstrapのJavaScriptで、Modalを使うメモ(とても短いサンプル) - Qiita
これに習い、以下のコードを導入してみました。
```
$("#domoNormalModal").modal('show');
```
一つ一つ説明していこうと思います。
$("#domoNormalModal")これは何に対して行う動作なのかを示しています。
今回のモーダルはサンプルからとってきており
```
このような構造になっています。
この先頭行のidが今回のフックになる部分です。
続いてmodal('show');の部分。こちらはそのままの意味で指定したidのモーダルを表示すると言う意味になります。
本来ならこれで表示されるのですが他の処理と組み合わせる際はこのままではうまくいきませんでした。
解決
初めに記述しましたが今回は質問と解答を消してからモーダルを出現させなければなりません。
加えて上記のコードでは出現されない場合があります。
初めの問題に関しては順番を示して上げなければなりません。こちら以前記事にも取り上げたwhenとdoneが必要になります。
二つ目の問題は記述方法です。下記のように記述してあげるとモーダルが出現します。
```
$("demoNormalModel").show();
```
出来上がったコードがこちらです。
一つ目の処理、whenで問題と選択肢をfadeOut=display: noneの状態にし画面から消しています。
二つ目の処理doneでモーダル全体を表示しています。
このように現状の処理とモーダルを組み合わせる場合は順番と動作を明確にする必要があったのです。
最後に
他にも詰まった部分はあったのですが大きな所ではこの点でした。
jqueryはとても便利ですが繊細な点が多々あります。
今後もポートフォリオで詰まった点を順次記録に残し後から見直せるようにしていこうと思います。
seed_fuで初期データを導入しようと思ったらエラーがでた話
プログラミングを本格的にスタートして5ヶ月目に入りましたさかもとです。
今回は以前紹介したseed_fuを使い初期データを導入しようと思ったらファイルの配置ミスによってエラーが出てしまったので復習の意味も込めてアウトプットしたいと思います。
今回のエラー
rails db:seed_fu を実行すると
ActiveRecord::InvalidForeignKey: Mysql2::Error: Cannot add or update a child row: a foreign key constraint fails (`(アプリ名_development`.`first_answers`, CONSTRAINT `fk_rails_a064cfe5d3` FOREIGN KEY (`first_question_id`) REFERENCES `first_questions` (`id`))
このようなエラーが出てきました。
現状
db/fixtures/first_anser.rb
db/fixtures/first_question.rb
ファイルの配置状況
思考
今回に関してはまずforeign_keyと書いてあるのでリレーションの外部キー制約がうまくいってないんだなと目星を付けました。
そこでファイルの中身をそれぞれみてみると記述に誤ったところやタイポなどは見当たりません。
そこでエラー文を検索してみます。すると下記記事を見つけました。
この中に答えがのっていました。是非解決にいく前にどこがおかしかったのか記事を読んで予測をしてみてください。
解決
結論から言うと、「ファイルの作成順」でした。
現状、fixturesファイルの中にfirst_answer.rbの下にfirst_question.rbがあります。
しかしリレーション的にはquestionが親でanswerが子なので先に親のquestionが作成されなければanswerに外部キーが導入されることはありません。
そこで今回の状況をみてみるとseed_fuはファイルの順序で上から作成されていきます。
つまりこのままだと先にanswerが作成されてしまうので外部キーにいれるidが存在せずエラーが発生すると言うことです。
ではどうすればいいか。これは添付記事の方法を採用しました。
ファイル名の先頭に数字で順番を明示してあげると言う方法です。
そうすることで順番が正確な位置に入れ替わりました。
これで再びrails db:seed_fuを実行するとうまく初期データが入ってくれました。
最後に
ファイルの順番で作成順が変わると言うことを完全に抜けていました。
思わずコードに目がいってしまいますが今後はこちらも気にしながら開発を進めていこうと思います。
jqueryで1クリック2機能導入を試みた際につまづいてしまった話
プログラミングを本格的にスタートして5ヶ月目に入りましたさかもとです。
今回は以前railsにjqueryを導入し他のですが、今回満を辞してフルにjqueryを使ったクイズアプリのフロントを作成していた時にハマってしまったので復習の意味も込めてアウトプットしたいと思います。
今回実装しようと思っている機能はこんな感じ
質問に対して3つの選択肢がありクリックすると現在の質問と選択肢が消え、次の質問が表示されるというものです。
今回この機能を実装しようと色々調べたのですが意外と調べるのに苦労したこと、そして似たような実装をしている記事があったのですが機能しなかったので記事にしました。
環境
rails 6.0.3
ruby 2.6.5
jqueryはwebpackerで導入しています。
view
dbにあらかじめseed_fuを利用して初期データを導入しそれをコントローラーから引っ張ってきてます。
これはわかりやすいようにと1問分で記述していますがリファクタリングをすればおそらく10行ぐらいで10問ほど表示できるのではと思っています。
score.js
webpackerでインストールしているのでapp/javascript/score.jsファイルを作成し、packs/application.jsで読み込んでいます。
今回のjqueryでの実装はこのようになりました。
1行づつ説明していこうと思います。
1行目:turbolinks : loadこれは「初回ページ読み込み&リロードで動くが、ページ遷移し
て該当ページに戻ってくるとjqueryが動かない!」という状況を回避するために
使用しています。turbolinks自体はページの遷移を早くする。みたいな認識だと
思うのですがgemを入れている場合、$(document).ready()では動きません。
2行目 : これはフロント<a></a>の中にあるclassとリンクしています。何が行われた時
にどうするのかの何かを明示しています。
4行目 : これは2行目の何がどうするかのどうするかの部分に当たります。今回の場合は
質問と選択肢を全て消すことから始まるのでdiv要素を指定しています。
6行目 : 4行目の後に次の質問と回答を出力しなくてはなりません。そこで次のdiv要素
の中にあるidを明示してあげることで引っ張ってきています。
ポイント
3,5行目 : $.when() と .done()
ここで詰まってしまいました。
おそらくjqueryのボタン関係の記事をみてもこの記述のあるものは少ないのではと思います。
これは何かというと処理を行う順番を表しています。
$.when() は初期動作の後に初めに実行するもの
. done() はその後に行う動作を明示しています。
( .fail()というものもあり、エラーが起きた際にどう言った処理を行うかを明示的に示すものもあります。)
Ajaxなどの非同期通信を行う場合、データベースからデータを読み込む場合に利用します。
今回の場合は後者が原因だったように思います。
最後に
jqueryは今まで一度だけ触ったことがあったのですが今回のようにガッツリ開発の中で使ったことがないのでわからないことが多々あります。
今後もつまづいたことをそのままにせずアウトプットしていこうと思います。
参考記事
$.when() | jQuery 1.9 日本語リファレンス | js STUDIO
$.when() | jQuery 1.9 日本語リファレンス | js STUDIO
railsにsorceryを導入した時に公式wiki通りにやったらハマった話
プログラミングを本格的にスタートして5ヶ月目に入りましたさかもとです。
今回はrailsにuser管理機能を実装するためにsorceryを導入した時にハマった話をアウトプットしていこうと思います。
sorceryって
sorceryは簡単にプロダクトの中にuser管理機能を導入することのできるgemです。
具体的にはgemをインストールして公式のwiki通りに進めるとuser新規登録機能とuserログイン機能に必要なモデルやマイグレーションファイル、その他いくつかの設定ファイルが作成され手間をかけずにuser周りの操作が実装できます。
これが公式wikiです。
Simple Password Authentication · Sorcery/sorcery Wiki · GitHub
この後はこの通りに進めていくので一読していただけると内容がわかりやすいと思います。
実装
① gemのインストール
gem 'sorcery'をgemファイルの中に入れbundleします。
② sorceryを実行
rails g sorcery:installで必要なファイル等も作成します。
するとdbにモデルを作成するためもととなるファイルが大きく2つ作成されます。
migrateファイル
user.rb
③ rails db:migrate
設定やvalidatesの書き込みなどあると思いますが今回はwikiの流れにそうのでここでmigrateします。
④ viewの実装
新規登録画面を実装します。
nameカラムを追加してbootstrapで装飾してますがほとんどwiki通りだと思います。
⑤ ブラウザで確認
最後にブラウザで新規登録できるか確認してみましょう。
?????????????????
これが今回、私がハマったエラーです。
思考
今回は公式は正しいと思い込んでしまいエラーをよくみなかったのが時間を取られてしまった大きな要因だったと反省しています。
例によって例のごとくエラーからざっくり内容を予測します。
ActiveRecord::StatementInvalid - Mysql2::Error:Table'mentalhealth_management_test_development.users' doesn't exist:
form_withで使うためにuserインスタンスをUser.newで作成しているところで起きています。内容はusersテーブルがMysqlの中に存在しないよと言っていると考えました。
予測を立てたのでschema.rbファイルを確認しにいきます。
テーブルは作成されていました。
ただテーブル名はUser ....ちょっと変です。
次にテーブルのもととなるマイグレーションファイルを見に行きます。
ここが原因でした。
sorceryで自動生成されたものですが本来テーブルは複数形で記載する必要があります。
ここがUserになっているせいでusersテーブルがないと言われてしまっていたのです。
解決
マイグレーションファイルを本来の形に修正しました。
emailに重複を避けるためにvalidatesでuniqueが貼られているのでadd_indexの記述も変更しました。
私はここの変更を忘れて半日はまりました。
これでrails db:migrateすると無事レンダリングすることができました。
最後に
公式は正しいと思い込み何か見落としたことがあるのではと実装順序を目をさらにして確認してしまいました。
エラーに真摯に向き合うことが大切だと学びました。
今後もエラーについてまとめていこうと思います。
bundle execとはなんなのか
プログラミングを本格的にスタートして5ヶ月目に入りましたさかもとです。
今回はbundle execを使用する意味が曖昧だったのでアウトプットしていこうと思います。
今回のエラー
The `rubocop' command exists in these Ruby versions:
2.6.3
2.6.4
rubocopを導入しファイルを生成するためにgithubを参照しながらgemを入れbundleし、rubocop --auto-gen-configをターミナルで打ったところ上記エラーが発生しました。
思考
初めて見るものだったのでとりあえずエラーメッセージを見てみるとどうもこのrubyのバージョンでこのコマンドは使えません。下記環境でなら使えます。という風に読み取りました。
今回の私の環境はruby 2.6.5だったので環境にあってないのだと考えます。
そこで調べていると環境変数を変えるなどの記事は見受けられますが以前入れた時のことを思い出すとbundle execを使用したなと思い調べた。
bundleって?
プロジェクトの中でgemのバージョンを管理します。
ツールの名前としてはbundler、コマンドはbundle.
bundle execとは
gem file内で指定されている全てのgemを実行可能にし、そのコマンドの利用も実行可能にします。
bundle execの有無で何が違うの?
有
現在開発を行っているプロジェクト内でコマンドを実行する。
gemfileに応じたバージョンを実行するためにrails〜のようなコマンド以外は基本的にbundle execを使用
無
rbenvで指定したrubyのバージョンに応じたシステム共通のコマンドが実行される。仮にシステム共通のものがなかった場合rails〜は使用されない。
解決
結論からいくと
bundle exec rubocop --auto-gen-config
こちらで無事作成されました。
rubocop特有のコマンドだったためgemでインストールした場合、gemfileのバージョンに応じて使用しなくてならなかった。システム共通のライブラリの保存場所を環境下にしてコマンドが実行されてしまっていたのでは。
というのが現段階の私の考えです。
正直曖昧な部分も多いので今後、追記していこうと思います。
参考文献
bundle exec | Bundler日本語ドキュメント | Ruby STUDIO
【Rails】結局bundlerって何?bundlerの仕組みを図解形 | Pikawaka - ピカ1わかりやすいプログラミング用語サイト
rbenv環境で特定バージョンのコマンドを実行する(特にrubocop) - None is None is None