このページの内容は以下のリポジトリに1日遅れで反映されます(記事執筆前に前日分をコミットしています)。
https://github.com/hkob/hkob_blog
はじめに
Rails Tips の 71 回目です。Rails ガイドに戻り、「concern を使う」をやってみます。個人的はあまり concern を使ったことがないので、今回試してみてうまく使えるようであれば自分のプロジェクトでも対応してみたいと思います。今日は status 属性を追加するところまでになる予定です。
9.3 concern を使う
concern を使うという内容ですが、最初は concern を使わない実装が行われます。まずは、status 属性を article と comment の両方に追加するための migration ファイルを作成します。ガイドでは CamelCase のもので説明していますが、私は underscore の方が好みなのでそれで行います。
$ bin/rails g migration add_status_to_article status:string invoke active_record create db/migrate/20240208115326_add_status_to_article.rb $ bin/rails g migration add_status_to_comment status:string invoke active_record create db/migrate/20240208115356_add_status_to_comment.rb
それぞれのファイルは以下のようになりました。null: false
を追加しています。
class AddStatusToArticle < ActiveRecord::Migration[7.1] def change add_column :articles, :status, :string, null: false end end
class AddStatusToComment < ActiveRecord::Migration[7.1] def change add_column :comments, :status, :string, null: false end end
migration しておきます。
$ bin/rails db:migrate $ bin/rails db:migrate RAILS_ENV=test
fixtures の articles.yml や comments.yml に status を追加しておきます。
article1: title: "This is the first article" body: "This is the body of the first article" status: "public" can_delete: title: "This is the second article that can be deleted" body: "This is the body of the second article" status: "private"
comment1: commenter: "user 1" body: "comment 1 for article 1" article: article1 status: "public" can_delete: commenter: "user 2" body: "comment 2 for article can_delete" article: can_delete status: "archived"
status には public, private, archived しか入れることができないのですが、このテストは明日に回します。今はとりあえず、article_spec.rb や comment_spec.rb に存在制約だけを付けてみます。
it_behaves_like "存在制約", %i[title body status]
it_behaves_like "存在制約", %i[commenter body article_id status]
このテストを追加させるためだけに、以下の記述をしてこのテストだけを通過させます。明日これを書き換えます。
validates :status, presence: true
おわりに
ここまで書いて値を限定する shared example (値限定制約)が作りたくなったので、今日はここで切ります。