料金マスタ (ActiveYaml) のモデル・YAMLデータを整備#8
Merged
Conversation
9ee2a8a to
e99d28f
Compare
Closed
e99d28f to
50d70c4
Compare
50d70c4 to
c0b6d7d
Compare
c0b6d7d to
ce30231
Compare
active_hash gem を導入し、Provider / Plan / AmpereBasedRate / UsageBasedRate を ActiveYaml モデルとして実装、料金体系を db/data/ 配下の YAML に格納する。 設計判断: - rate は浮動小数点誤差を避けるため YAML 上は文字列で記述し、getter で BigDecimal に変換する - 「従量課金のみプラン」(Looopでんき) は ampere_based_rates レコードの有無を真実とし、 Plan#metered_only? でその意味づけを与える(フラグを別途持たせると整合性が壊れ得るため) - ActiveHash の belongs_to / has_many は ActiveRecord の挙動と異なるため、 Rails/RedundantPresenceValidationOnBelongsTo / Rails/HasManyOrHasOneDependent を該当ファイルで除外 - 後段で日本語のエラーメッセージを返すため、デフォルトロケールを ja に統一 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
データ整合性 spec では initializer での自動 fail を避け、テスト時に全レコードの valid? を検証することで本番起動を不能にしないようにする(参照整合性とプラン数、 metered_only? の業務的不変条件もここで担保)。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
YAML を初回読み込みするまでアクセサが定義されない暗黙の挙動に依存しないようにする。 Klass.all を先に呼ばずに Klass.new(...) ができ、ファイルを開くだけでスキーマが 分かるようになる。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
config.i18n.default_locale = :ja に切り替えたものの、Rails / ActiveModel が 同梱する標準メッセージ翻訳には ja が含まれず "Translation missing" になるため、 rails-i18n を追加して presence / inclusion 等のメッセージを日本語化する。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
expect(record).to be_valid, MSG の MSG は呼び出し前に eager 評価されるため、 matcher 側が valid? を呼ぶ前の状態(errors が空)で組み立てられていた。 先に valid? を呼んで errors を確定させてから文字列補間する。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
YAML データの型や境界値の不正をモデル単体で検出できるようにする。 設計判断: - rate は getter が BigDecimal 変換を行うため、numericality が getter を呼ぶと "abc" のような変換不能値で ArgumentError になる。代わりに raw 値を直接読む custom validator (rate_must_be_number) を実装し、:not_a_number / :greater_than_or_equal_to で表現する - presence 等の他バリデーションも同様に getter で落ちるため、 read_attribute_for_validation を rate キーだけ raw 値に差し替える - foreign key と数値属性の numericality は presence と併用するため allow_nil: true を付けてエラーを重複させない - 料金レンジの連続性 (low=1 起点 + 段の間に穴/重複なし) を data_consistency_spec に加え、kWh 範囲のデータ的不変条件を保証する Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
これまでは spec/models/ のスポットチェック (first / find(1)) と data_consistency の全レコード valid? からの間接保証だけだったため、 誤って rate getter を変更したときの検出網が弱かった。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
ce30231 to
fa4507f
Compare
- UsageBasedRate#low_must_not_exceed_high を `>` から `>=` に変更し low と high が同値のセグメント(範囲 0kWh)を invalid とする - ja.yml のエラーメッセージを「以下でなければなりません」→ 「より小さくなければなりません」に修正(仕様と一致させる) - モデル spec の #rate テストを find(id) / first 依存から new(...) による任意値渡しに変更し YAML データ変更で壊れない構造にする - plan_spec のアソシエーション検証を件数・具体名から型(be_a)のみに絞り、 件数の正確性は data_consistency_spec に委譲する - plan_spec の #metered_only? を特定 ID 列挙から new(id: 9999) / all.find による振る舞いベースの検証に変更する Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Base automatically changed from
feature/2604/en-Barry/environment-setup
to
develop
May 12, 2026 10:26
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
要約
Issue #5(ActiveHash gem 導入 / 4 モデル定義 / YAML 料金データ / データ整合性バリデーション)をすべて解決する。
Closes #5
非自明な設計判断
numericalityではなく独自バリデーターで rate を検証している理由numericalityは getter を経由するため、BigDecimal 変換失敗時にバリデーション自体がクラッシュする。またread_attribute_for_validationをオーバーライドしているのも同じ理由で、presence バリデーターが getter 経由でArgumentErrorを起こすのを防ぐため。データ整合性の検証を initializer ではなく spec に置いた理由
initializer で起動時 fail させると本番起動が不能になるリスクがあるため。
kilowatt_hour_low == kilowatt_hour_highを invalid とした理由low == highは現行の料金体系に存在せずデータ入力ミスとみなすべきであるため、low < highのみを有効とした。テストケース一覧
spec/data_consistency_spec.rb(データ整合性)
spec/models/*_spec.rb(モデルバリデーション)
各モデルの validates に対する正常系 / 異常系ケース、アソシエーション、#rate / #metered_only? の振る舞い