- 1. 【Rails7】renderメソッド注意点【エラーハンドリング】
- 2. マイページを編集するときにパスワードなしで編集可能にする
- 3. アクション間で同じインスタンス変数を使い回す方法
- 4. いいコード悪いコードまとめ16章設計を妨げる開発プロセスとの戦い
- 5. いいコード悪いコードまとめ15章設計の意義と設計への向き合い方
- 6. コードの構造や複雑さを示すVScode拡張機能
- 7. 【Rails】バリデーションをスキップ
- 8. 【Rails】メモ化
- 9. 【Rails】DRYなコード
- 10. いいコード悪いコードまとめ14章モデリング リファクタリング 既存コードを成長に導く技
- 11. いいコード悪いコードまとめ13章モデリング クラス設計の土台
- 12. いいコード悪いコードまとめ12章メソッド(関数) 良きクラスには良きメソッドあり
- 13. いいコード悪いコードまとめ11章コメント
- 14. ジャンル登録機能実装
- 15. いいコード悪いコードまとめ10章悪魔を呼び寄せる名前
- 16. EC2上にRails + Selenium + Chromeの実行環境を構築する
- 17. Runa: Ruby で中規模アプリケーションを書くためのフレームワーク
- 18. コードの原則をリスト化してみた(追記予定)
- 19. いいコード悪いコードまとめ7章 コレクション〜ネストを解消する構造化技法〜
- 20. floatやらdecimalやら倍数不動小数点やら
【Rails7】renderメソッド注意点【エラーハンドリング】
Railsガイド
https://railsguides.jp/v7.0/layouts_and_rendering.html## 結論から
エラーハンドリングをしたい場合
render :edit, status: :unprocessable_entity
この後半部分が必要です。※Rails7で仕様が変わっています。
以前はデフォルトでバリデーションエラーが発生した場合、自動的にこのステータスコードが設定されていました。
よって:unprocessable_entityを明示的に指定する必要はありませんでした。## status: :unprocessable_entityとは
HTTPステータスコードの一つで、422 Unprocessable Entityを表します。このステータスコードは、リクエストがサーバーに到達したが、サーバーがリクエストを理解できない場合に使用されます。
一般的に、クライアントが送信したデータが不正な場合や、バリデーションエラーが発生した場合にこのステータスコードが利用されます。
## 記載しないとどうなるのか
バリデーションエ
マイページを編集するときにパスワードなしで編集可能にする
## はじめに
初めまして、プログラミングスクールGeekSalonのWebコースメンターをしています。今回の記事は、ユーザーマイページ(プロフィールページ)を編集する際にパスワードを入力せずに編集を可能にする方法をお教えします。
## 前提
・Railsバージョン: 5.0以上
・Deviseバージョン: 4.2以上
・ログインページが実装されている
・ユーザーマイページ(プロフィールページ)が実装されていることDeviseでは、アカウントをアップデートする際に、3つのパスワード情報が必要になります。
**password**
**password_confirmation**
**current_password**パスワードを3回も打つ理由としては、**パスワードの誤入力を防止、不正なアクセスを防止**などが挙げられます。ただ、プロフィールを編集するために、パスワードを3つも入力させるのは、マジで面倒です。
なので、パスワードなしで実装する方法をこの記事のゴールとします。
## 1.RegistrationsControllerの作成
“`
ra
アクション間で同じインスタンス変数を使い回す方法
## 本記事の内容
アクション間で同じインスタンスを使いたいことがありました。
今回は、アクション間で同じインスタンス変数を使い回す方法を解説しています。## 要件
1.ユーザー登録画面では、ユーザー名とメールアドレスのみを入力
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985135/e6e21e29-2e65-b582-a161-6ad67ae24eac.png)2.入力されたメールアドレス宛に確認コードを送信、ユーザーが確認コードを入力する
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985135/a0f7edb8-af25-2681-b832-f51a94625c00.png)このように、「ユーザー名・メールアドレス・確認コード」の3つを同じFormオブジェクトで管理しているが、別々のviewでそれぞれ入力したい場合があります。
この時、ユーザー登録画面から確認コード入力画面
いいコード悪いコードまとめ16章設計を妨げる開発プロセスとの戦い
# チームメンバーとのコミュニケーションを密にとっているか
他のチームメンバーと同じ開発をしていた、やっていると思っていたらやっていなかったなどとならないように密にコミュニケーションを取る必要がある。
コンウェイの法則(コンウェイの法則とは、ソフトウェアシステムのアーキテクチャは開発チームの組織とよく似る)という法則から考えてもコミュニケーションは重要
# チームメンバーの心理的安全性は確保されているか
Gogoleが2012年に採用したことが脚光を浴びた概念。これは成功に導くチームを構築する上で重要で、意見や提案をする上で、冷笑されたり、煙たがられたり、聞く耳を持たれない状態ではうまくいかないということ。# より早く実装完了することに気を取られていないか
# クラス設計と実装のフィードバックサイクルを回しているか
仕様変更の際には最低でもメモ書き程度のクラス図を書くこと。責務や凝集性などの観点から問題ないかをチームでレビューし、なさそうであれば実装に取り掛かる。取り掛かってから見落としに気づくことも多々あるので、それをクラス図にフィードバックすること。# 厳密に設計しすぎてい
いいコード悪いコードまとめ15章設計の意義と設計への向き合い方
# 課題を見据えているか
課題が見えないとそもそも設計する意識が生まれない# メソッド10行以内、クラス100行以内か
RuboCopのデフォルトでは、コードの行数とクラスの行数が10と100だ。違反すると警告される。# サイロマティック複雑度が15以内に収まっているか
| 循環的複雑度 | 複雑さの状態 | バグ混入確率 |
|:-:|:-:|:-:|
| 10以下 |非常にいい構造 |25% |
| 30以上 |構造的なリスクあり |50% |
| 50以上 |テスト不可能 |70% |
| 75以上 |いかなる変更も誤修正を生む |98% |# クラス内部で取り扱う概念が4±1になっているか
# コード分析をサポートする各種ツール
Code Climate Quality
Understand
VS Code シンタックスハイライト
コードの構造や複雑さを示すVScode拡張機能
良いコード悪いコードという著書の中に循環的複雑度(サイクロマティック複雑度)という言葉が出てきました。これはコードの構造的な複雑さを示していて、条件分岐やループ処理が増える、ネストが増えるなどの要因によって循環的複雑度が高い数値を示します。以下はその目安です。
| 循環的複雑度 | 複雑さの状態 | バグ混入確率 |
|:-:|:-:|:-:|
| 10以下 |非常にいい構造 |25% |
| 30以上 |構造的なリスクあり |50% |
| 50以上 |テスト不可能 |70% |
| 75以上 |いかなる変更も誤修正を生む |98% |これらは早期リターンやストラテジパターンなどにより低減可能です。
で、調べてみるとVS Codeの拡張機能に
`Codalyze – Code Complexity Report Generator`というものがありました。Updateは2020年の8月で止まっていますが、使ってみた感じは結構良さげでした。
ただ、詳細は見れないのでその辺りは他にいいのがあったら使ってみたいなという感じです。
http
【Rails】バリデーションをスキップ
# validate: false
– https://railsguides.jp/active_record_validations.html
>saveにvalidate: falseを引数として与えると、saveのバリデーションをスキップすることが可能です。この手法は十分注意して使う必要があります。
save(validate: false)– こんな時に使用
– データパッチをする必要があるが、バリデーションが走り登録できない
– 仕様上、Modelに定義したバリデーションは変更したくない
“`sample.rb
ActiveRecord::Base.transaction do
# 更新
contract.assign_attributes(contract_kind: MONTHLY, updated_system: SYSTEM_NAME, updated_user: UPDATED_USER)
contract.save!(validate: false)
end
“`
【Rails】メモ化
– 一度呼び出されてから結果が変わらないものはメモ化してしまう
– 呼び出されるたびにロジックやSQLが実行されるのを防ぐため、実行結果を丸々キャッシュする“`sample1.rb
def position_chief?
@position_chief ||=
if registration_date.nil?
false
else
position = member.position
position.present? && position.chief?
end
end
“`“`sample2.rb
def invoice?
@invoice ||= payment_date >= Date.new(2023, 10, 1)
end
“``||=`により
– **nil** または**false**であれば、右辺を代入する。
– **nil** または**false**以外であれば、2回目以降の呼び出し時は変数に格納された値を実行する。:::note
メモ化によって再実行を避けることが
【Rails】DRYなコード
# DRY原則-二重化の過ち
`DRY原則`(**Don’t Repeat Yourself** = 繰り返しを避けること):::note
システム内の二重化を最小限に抑えることを目的としている
::::::note warn
DRY原則を破るということは、同じ知識を2箇所以上に記述すること。
この場合、片方を変更するのであれば、もう片方も変更しなければいけなくなる。
:::開発自体の理解とメンテナンスを容易にする唯一の方法は、DRY原則に従うこと。
「すべての知識はシステム内において単一、かつ明確な、そして信頼できる表現になっていなければならない」:::note
既にあるものを簡単に見つけ出して再利用できるようにし、同じものを何度も作成しないような環境を構築すること
:::# 重複しているクエリを修正する
## 最後の条件だけ違うパターン
“`共通コード.rb
transaction_arel = Transaction.arel_table
credit_arel = Credit.arel_table
shop_arel
いいコード悪いコードまとめ14章モデリング リファクタリング 既存コードを成長に導く技
# 条件は読みやすいか
以下のように論理否定を使ったりすると読み替えるのが面倒
“`
if customer.isEnabled?
if !customer.isEnabled?
“`
したがって以下のように書き換える
“`
if customer.isEnabled?
if customer.isDisabled?
“`# ベタ書きロジックを目的を表すメソッドに置き換えているか
以下のように書いていると、理解に手間がかかる
“`
if customer.posessionPoint.amount < comic.currentPurchasePoint.amount ``` したがって、以下のようにメソッドを用意すれば可読性が上がる。 ``` def isShortofPoint(comic) return customer.posessionPoint.amount < comic.currentPurchasePoint.amount end ``` # テストを使用しよう テストコードを用いたリファクタリングの流れ 1. あるべき構造の雛形クラスをある程度作る
いいコード悪いコードまとめ13章モデリング クラス設計の土台
モデルとは、特的の目的達成のために最低限考慮が必要な要素を備えたもの
# 目的別にモデリングしているか
例えば、Userというモデルだけでは対応できないことが多々ある。Userと言ってもさまざまな性質を持つわけなので、それに応じたモデルを検討すること。# モデルの見直し
* そのモデルが達成しようとしている目的を全て洗い出す
* 目的それぞれ特化したモデリングをし直す
* 目的駆動名前設計に基づき、モデルに命名する
* モデルに目的外の要素が入り込んでいる場合、さらに見直す# クラスや実装の中での気づきをモデルにフィードバックしたか
実装を進めたりする中で、モデルの過不足に気づくことは多い。それを必ずすぐに反映させること。# 設計を繰り返し改良しているか
いいコード悪いコードまとめ12章メソッド(関数) 良きクラスには良きメソッドあり
# 自分のクラスのインスタンス変数を使っているか
あくまでも原則だが、他のクラスのインスタンス変数を変更するメソッド構造にしては行けない。変更したいインスタンス変数を持つクラスに変更メソッドを実装しよう。# コマンド・クエリ分離になっているか
コマンド(変更)とクエリ(問い合わせ)のどちらか一方だけを行うように設計しよう。
同時に行うことをモディファイアといい、避けられないケースもあるが、なるべく避けるようにしよう。# 引数は可能な限り少なくなっているか
多くなりそうな場合、別クラスへの分割を検討しよう
いいコード悪いコードまとめ11章コメント
# 退化コメントになっていないか
開発が進むにつれて元あったコメントは更新されずに退化していくことが多い。コメントは劣化コピーに過ぎないことを理解しよう。# ロジック更新時にコメントも更新したか
# 可読性の悪いロジックを捕捉説明するようなコメントを書いていないか
上述の通り、コメントは退化しやすい。メソッド名を改善しよう。# ロジックの意図や仕様変更時の注意点をコメントしたか
# ドキュメントコメントを使用しているか
YARD,RDocなどrubyでもドキュメントコメントを使用できる。
https://qiita.com/kmats@github/items/0c8919a65afbe18e9e37
ジャンル登録機能実装
はじめに
bootstrap導入済
namespases使用
devaice導入済
itemモデル genleモデル 作成済
商品登録ページ作成済
________
完成イメージ
ジャンル一覧・ジャンル登録(indexページ)
![スクリーンショット 2023-07-23 13.47.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492906/f4691ccf-e93e-3ec9-e91e-32c068552689.png)
ジャンル更新ページ(edit)
![スクリーンショット 2023-07-23 13.49.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492906/46847e7e-69ab-a644-7453-7046e766c7cf.png)### モデル設定
ジャンルモデル追加
“`
$ rails g model Genre name:string
$ rails db:migra
いいコード悪いコードまとめ10章悪魔を呼び寄せる名前
目的駆動名前設計:名前から目的や意図が読み取れることを特徴とする
# 命名が関心を分離できているか
例えば、商品というクラスという名前にreservationsやorders、shipmentsなどのような関心ごと全てが含まれていては密結合となりよろしくない。命名したときにこれではカバーする範囲、つまり関心ごとが広すぎる。したがって、関心の分離をすることが重要。「関心ごと、つまりユースケースや目的、役割ごとに分離する」わけである。
例えば、商品クラスにいろいろなロジックが含まれている場合
予約品、注文品、在庫品、発送品のように分割して行けば良い。# 大雑把で意味が不明瞭な命名になっていないか
先ほどの商品という名前はさまざまな状況をフォローできそうな名前だが、裏を返せばなんでも欠けてしまうクラスとなり、目的が不明なオブジェクトとなってしまう。# 命名のポイントを押さえているか?
## 可能な限り具体的で、意味範囲が狭い、特化した名前になっているか
このメリットとしては
* 名前とは無関係なロジックを排除しやすくなる
* クラスが小さくなる
* 関係するクラスの個数が少な
EC2上にRails + Selenium + Chromeの実行環境を構築する
# 前提
– AWS EC2 : Amazon Linux 2023 AMI 2023.1.20230719.0 x86_64 HVM kernel-6.1
– このAMIじゃないとこの後実行する行うコマンドで、Google Chromeがダウンロードできない可能性があるので注意。
– Ruby : v3.2.0
– Ruby on Rails : v7.0.5
– bundler : v2.4.12
– Node : v16.20.0Ruby on Railsが実行できる環境はすでに構築しているものとします。
`Webdrivers::Chromedriver.required_version = “114.0.5735.90”`というのを指定すると、Webdriverで自動的にChromeDriverをインストールして、それを勝手に利用するようになっていました!
以前までは`brew install chromedriver`を実行してChromeDriverをダウンロードして実行していましたが、その必要もなくなったようです。
# 環境構築
環境構築する上
Runa: Ruby で中規模アプリケーションを書くためのフレームワーク
src: [ブログのおんがえし](https://ongaeshi.hatenablog.com/entry/2023/07/23/113420)
[Runa](https://github.com/ongaeshi/runa) という Ruby で Gem を使ったり複数ファイルで構成された中規模のアプリケーションを簡単に書くためのフレームワークを作っています。
# Runa を作った経緯
– Ruby は単独のスクリプトファイルとして実行するときは取り回しも簡単で大変使いやすい(小規模アプリケーション)
– が、特定の gem に依存したり複数ファイルで構成されるようなアプリケーションを作ろうとするとスタンダードな方法が用意されておらず(特に配布や共有のことを考えると)敷居が高くなってしまう(中規模アプリケーション)
– これが今まで余り問題にならなかったのは、Web アプリであれば Rails を使えばフレームワークがその辺りを内包してくれたり、コンソールアプリケーションなら gem で配布するみたいな方法でやりくりしてきた経緯がある。しかし gem で配布するには Ruby
コードの原則をリスト化してみた(追記予定)
いいコード悪いコードを読んで、重要そうな項目を抜粋してみました。まだ数章読めていい無いので今後追記していきます。
“`
* 省略せずに意図が伝わる名前を設計しているか
* 変数を使い回していないか
* 目的ごとの変数を用意しているか
* 意味のあるまとまりでメソッド化しているか
* 関係しあうデータとロジックをクラスにまとめているか
* コンストラクタで確実に正常値を設定しているか
* 変更したい場合は新しいインスタンスを作成しているか
* 引数に渡せる型を限定しているか
* 引数は可能な限り少なくなっているか
* 再代入していないか
* デフォルトは不変にしているか
* 条件分岐を一箇所にまとめているか
* フラグ引数やinteger引数を使っていないか
* パッとみて、何をするメソッドが想像がつくか
* メソッドが単機能で分離されているか
* 標準ライブラリに同じような機能のメソッドはないか
* 早期nextで条件分岐のネストを解消できないか
* 早期breakで条件分岐のネストを解消できないか
* デッドコードは消えているか
* YAGNI原則に則っているか
* マジックナンバ
いいコード悪いコードまとめ7章 コレクション〜ネストを解消する構造化技法〜
# 標準ライブラリに同じような機能のメソッドはないか
実は便利なメソッドがあったのに存在を知らずに自分で書いてしまった!なんてことは誰しも経験したことがあるのではないでしょうか。そうならないためにも、一度調べてみてから、なければ自分で書く癖をつけたいですねー。# 早期nextで条件分岐のネストを解消できないか
例えば、以下のように多重分岐している場合、これは早期nextで解消できるかもしれません。
“`
number = 5if number == 1
puts “number is 1”
elsif number == 2
puts “number is 2”
elsif number == 3
puts “number is 3”
elsif number == 4
puts “number is 4”
elsif number == 5
puts “number is 5”
end
“`
以下のように書くとスッキリですね。
“`
number = 5next if number == 1
next if number == 2
next if
floatやらdecimalやら倍数不動小数点やら
# floatやらdecimalやらで沼にハマったので忘備録
なんかfloatって便利そうだから使ったらいいかなーという気楽な気持ちで使ったら面倒なことになりました。
もはや`float`の使い所がわからなくなった…# floatだと精度が低い!
例えば、以下のような値をfloatした時に思っている挙動と違いました。“`
1.111111111111111111222222222.floor(20)
=> 1.1111111111111112 #小数点以下が16桁しかない…
“`他にも以下のような計算をしても誤差が出てしまいます。
“`
pry(main)> 1 – 0.9
=> 0.09999999999999998
pry(main)> 0.9.class
=> Float
“`これらはfloat型であることに起因しています。
理由は以下の説明の通り。
“`
Rubyにおいて、浮動小数点数の精度は倍精度浮動小数点数(double-precision floating point)によって制御されます。この倍精度浮動小数点数は通常64ビットで表現さ