- 1. 【Ruby on Rails】マイグレーションの仕組みを理解して「分からない」から抜け出そう?【初心者向け】
- 2. プロを目指す人のためのRuby入門を読んだ感想
- 3. いいコード悪いコードまとめ5章低凝集
- 4. 注文ステータス enum日本語での実装
- 5. 管理者側 注文内容一覧ページ
- 6. letter_opener_webって?
- 7. アプリケーションを作成する手順
- 8. enum
- 9. BigDecimal型のデフォルト四捨五入を変更する方法
- 10. 【Rails7】renderメソッド注意点【エラーハンドリング】
- 11. マイページを編集するときにパスワードなしで編集可能にする
- 12. アクション間で同じインスタンス変数を使い回す方法
- 13. いいコード悪いコードまとめ16章設計を妨げる開発プロセスとの戦い
- 14. いいコード悪いコードまとめ15章設計の意義と設計への向き合い方
- 15. コードの構造や複雑さを示すVScode拡張機能
- 16. 【Rails】バリデーションをスキップ
- 17. 【Rails】メモ化
- 18. 【Rails】DRYなコード
- 19. いいコード悪いコードまとめ14章モデリング リファクタリング 既存コードを成長に導く技
- 20. いいコード悪いコードまとめ13章モデリング クラス設計の土台
【Ruby on Rails】マイグレーションの仕組みを理解して「分からない」から抜け出そう?【初心者向け】
# ? はじめに
記事を開いていただきありがとうございます!
この記事では主にRailsの初学者に向けて、マイグレーションの仕組みについて分かりやすく解説します!私が初学の時にやっていた、 **「とりあえず何か分からないけど `rails db:migrate` や `rails db:rollback` を実行してみる」** がみなさんから無くなるように、仕組みを理解できるように、順を追って説明していきます!
:::note info
この記事で書く事
・ よく聞くマイグレーションとはそもそも何か
・ `rails db:migrate` や `rails db:rollback` って何してるの?
::::::note alert
この記事で書かない事
・ SQLの解説
・ データベースの構造
・ Railsのコードの書き方
:::# ? データベースの作り方
まずそもそもデータベース(RDB)はどうやって作るのでしょう?
データベースは `MySQL` や `PostgreSQL` といったデータベースエンジンと呼ばれるものに、 **「データベースを作るよ」** や
プロを目指す人のためのRuby入門を読んだ感想
[プロを目指す人のためのRuby入門](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%92%E7%9B%AE%E6%8C%87%E3%81%99%E4%BA%BA%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AERuby%E5%85%A5%E9%96%80%EF%BC%BB%E6%94%B9%E8%A8%822%E7%89%88%EF%BC%BD-%E8%A8%80%E8%AA%9E%E4%BB%95%E6%A7%98%E3%81%8B%E3%82%89%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA%E3%83%BB%E3%83%87%E3%83%90%E3%83%83%E3%82%B0%E6%8A%80%E6%B3%95%E3%81%BE%E3%81%A7-Software-Design-plus-%E4%BC%8A%E8%97%A4-ebook/dp/B09MPX7SMY/ref=sr_1_1?__mk_ja_JP=%E3%8
いいコード悪いコードまとめ5章低凝集
# 凝集度とは
凝集度とはモジュール内における、データとロジックの関係性の強さを表す指標。これはクラス、パッケージ、レイヤーなどの場合も同じである。この凝集度が高ければ変更に強い、望ましい構造と言える。
例えば、以下は低凝集なコードである。
一見、注文クラスの中だから、金額計算や注文管理のメソッドが混ざっていてもよさそうに思えるが、これはよろしくない。なぜなら、コードが一つの関心事に集中していないため、理解しやすく保守しにくいからだ。このコードでは、金額の計算と注文の管理の両方の機能が混ざっている。
そのため、このコードを理解するには、金額の計算と注文の管理の両方の知識が必要になる。
また、このコードを保守するには、金額の計算と注文の管理の両方のコードを変更する必要もある。このコードを改善するには、金額の計算と注文の管理の機能を分離すればよい。
例えば、金額の計算はOrderCalculatorクラスに、注文の管理はOrderManagerクラスに移譲することができる。これにより、コードが一つの関心事に集中し、理解しやすく保守しやすくなるわけだ。
“`
class
注文ステータス enum日本語での実装
:cherry_blossom: **はじめに**
bootstrap導入済
namespases使用
devaice導入済
ordersモデル 実装済
admin/orders_controller 作成済
注文機能作成済
public/orders_controller.rb 作成済
“`public/orders_controller.rb
def create
@order = Order.new(order_params)
@order.customer_id = current_customer.id
@order.order_status = 0
@order.savecurrent_customer.cart_items.each do |cart_item|
@order_datail = OrderDatail.new
@order_datail.order_id = @order.id
@order_datail.item_id = cart_item.item_id
管理者側 注文内容一覧ページ
はじめに
bootstrap導入済
namespases使用
devaice導入済
costomersモデル、ordersモデル 実装済
注文機能実装済
_____
:star:gimfailにenum導入して日本語で表記されるようにする
“`diff_ruby
gem ‘rails-i18n’
gem ‘enum_help’
“`
“`
$ bundal install
“`
“`scheme.rb
create_table “cart_items”, force: :cascade do |t|
t.integer “customer_id”, null: false
t.integer “item_id”, null: false
t.integer “quantity”, null: false
t.datetime “created_at”, precision: 6, null: false
t.datetime “updated_at”, precision: 6, null: false
t.integer
letter_opener_webって?
# letter_opener_webってなに??
タイトルの通り`letter_opener_web`について解説したいとおもいます。
#### letter_opener_webとは
開発環境でメールを送信した際に、ブラウザでそのメールを確認するためのツールです。
本番環境で実際にメールを送る代わりに、このツールを使ってメールの内容や送信先を確認することができます。
#### 使用方法
Gemfileにletter_opener_webを追加
“`ruby:Gemfile
gem ‘letter_opener_web’, ‘~> 1.0’
“`
“`
$ bundle install
“`
これで使えるようになります!
アプリケーションを作成する手順
すでに作りたいアプリケーションのイメージがある場合、下記の3つをざっくりと考え始めること
“`
1. どんなページが必要か
2. どんなページ遷移になるのか
3. そのページにはどんな機能があるのか
“`作りたいアプリケーションにはどんなページが必要なのか、どんなボタンをどこに置くのかなどを考えることで、曖昧だった機能が見えてきたり、テーブル構造のアイデアが浮かんだりするからです。
また、この作業を「要件定義」とも言います。要件定義を行うことで、どのようなテーブルやカラムが必要なのかも明確になります。
(例)ログイン画面
ログイン画面の機能をざっくりと書き出すと、下記の通り
* 必要項目を入力し、ログインボタンを押すと認証される
* 認証に通ると、ユーザー一覧画面に移動する
* ネットワーク障害や認証失敗などでエラーが起こった場合は、エラーメッセージが表示される
* 「初めての方はこちらをクリック」を押すとページ遷移はせず、サインアップ画面が表示される
enum
# enumのメリット
* データの整合性と可読性の向上
* データベースのスキーマの柔軟性
これはかなり大きいと思います。例えば、booleanで設定すると、今後の選択肢が増えた場合に変更できなくなってしまいます。しかし、enumで設定しておくと後からのデータベース変更を柔軟に行うことができます。(まあ可能な限り変更しないことが理想ではあるんですが、、、)# マイグレーションファイルで列挙型を定義
“`
rails g migration AddColumnStatusToUser
invoke active_record
create db/migrate/20230511075254_add_column_status_to_user.rb
“`
“`
class AddStatusToUsers < ActiveRecord::Migration[6.0] def change add_column :users, :status, :integer, default: 0 end end ``` ``` rails db
BigDecimal型のデフォルト四捨五入を変更する方法
# 書き方
書き方は単純なのですが、調べても全然出てこなかった!!
“`models/Hoge.rb
class Hoge < ApplicationRecord BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_DOWN) belongs_to :foobar end ``` https://docs.ruby-lang.org/ja/latest/method/BigDecimal/s/mode.html # 例外処理 計算結果が非数(NaN)やゼロによる除算になったときの処理を定義することができます。 ``` flag = false # デフォルト値 f = BigDecimal::mode(BigDecimal::EXCEPTION_NaN,flag) f = BigDecimal::mode(BigDecimal::EXCEPTION_INFINITY,flag) f = BigDecimal::mode(BigDecimal::EXCEPTION_UNDERFLOW,flag) f = Big
【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と言ってもさまざまな性質を持つわけなので、それに応じたモデルを検討すること。# モデルの見直し
* そのモデルが達成しようとしている目的を全て洗い出す
* 目的それぞれ特化したモデリングをし直す
* 目的駆動名前設計に基づき、モデルに命名する
* モデルに目的外の要素が入り込んでいる場合、さらに見直す# クラスや実装の中での気づきをモデルにフィードバックしたか
実装を進めたりする中で、モデルの過不足に気づくことは多い。それを必ずすぐに反映させること。# 設計を繰り返し改良しているか