教材の内容に関係のない質問や教材とは異なる環境・バージョンで進めている場合のエラーなど、教材に関係しない質問は推奨していないため回答できない場合がございます。
その場合、teratailなどの外部サイトを利用して質問することをおすすめします。教材の誤字脱字や追記・改善の要望は「文章の間違いや改善点の指摘」からお願いします。
この章ではカードを作成・詳細・編集・削除する機能を実装していきます。作成・編集・削除機能は4章のリスト機能で実装してきて、似ている箇所は多くあります。プログラミングを学習する上で大事なことは何度も反復することです。この章でWebアプリケーション開発の基本的なことをマスターしましょう。
本パートでは、Cardモデルを作成し、アソシエーションの設定まで行います。
では実際に進めていきましょう。
カード機能を作成するにはデータベースにカードの情報を保存する処理が必要になります。
なのでまずデータベースのやり取りを行うモデルを作成していきます。
カード作成に必要な情報は以下の2つになります。
Copied!- カードのタイトル
- カードの詳細
- 誰が投稿したかカードの情報
この3つの情報を格納するためにcardsテーブルを作成します。
cardsテーブル構成は以下のようになります。
カラム名 | データ型 |
---|---|
title | string |
memo | text |
list | references |
references型
で保存すると、list_id
を外部キーとして明示的に指定できます。
外部キーとは関連したテーブルの間を結ぶために設定する列のことです(今回でいうとlistsテーブルとcardsテーブル)。
モデルを作成するには、rails g model モデル名
というコマンドでモデルを作成できます。
では、Cardモデルを作成するに以下のコマンドを実行してください。
Copied!$ rails g model Card
上記のコマンドで新しくマイグレーションファイルも作成されます。
早速その作成されたマイグレーションファイルを以下のように編集してください。
Copied!db
└── migrate
└── xxxxxx_create_cards.rb
db/migrate/xxxxxx_create_cards.rb123456789101112 Copied!class CreateCards < ActiveRecord::Migration[6.0]
def change
create_table :cards do |t|
# ==========ここから編集する==========
t.string :title, null: false, limit: 255
t.text :memo, limit: 1000
t.references :list, null: false, foreign_key: true
# ==========ここまで編集する==========
t.timestamps
end
end
end
references型は カラム名+"_id" がテーブル名として設定されるので、今回cardsテーブルにはlist_id
というカラムが追加されます。
limit
制約はデータ型の最大幅を指定するために使います。
では、マイグレーションファイルを実行してcardsテーブルを作成します。
Copied!$ rails db:migrate
上記のコマンドを実行すると下記のような実行結果が表示されます。
Copied!== 20190918070826 CreateCards: migrating ======================================
-- create_table(:cards)
-> 0.0039s
== 20190918070826 CreateCards: migrated (0.0041s) =============================
モデルを作成したらアソシエーションの設定を行います。
アソシエーションとは、2つのモデル同士のつながりを指します。モデルとモデルの間には関連付けを行う必要があります。
参考)Active Record の関連付け (アソシエーション)
まずListモデルとCardモデルのアソシエーションを設定していきます。
上記2つのモデルの関係性は以下のようになります。
Copied!- リストに複数のカードを作成することができる
- カードAに関して、カードAに紐づいているリストは1つしかない
このような関係のことを「1対多の関係」と言います。
では、app/models/list.rb
に以下のコードを追加してください。
Copied!app
└── models
└── list.rb
app/models/list.rb12345678 Copied!class List < ApplicationRecord
belongs_to :user
# ここに追加
has_many :cards, dependent: :destroy
validates :title, length: { in: 1..255 }
end
ruby1 Copied!has_many :cards, dependent: :destroy
has_many
は、他のモデルとの間に「1対多」のつながりがあることを示します。(「1側」にhas_manyを追加します。)
has_many
が使用されている場合、「反対側」のモデルでは多くの場合belongs_to
が使われます。
またdependent: :destroy
をつけることで、オブジェクトが削除されるときに、関連付けられたオブジェクトのdestroy
メソッドが実行されます。つまり今回で言うと、リストが削除されたら、そのリストに紐づくカードも削除します。
参考)Active Record の関連付け (アソシエーション) :dependent
次にapp/models/card.rb
に以下のコードを追加してください。
Copied!app
└── models
└── card.rb
app/models/card.rb1234 Copied!class Card < ApplicationRecord
# この行を追加
belongs_to :list
end
これでListモデルとCardモデルのアソシエーション設定ができました。
値がデータベースに保存される前に、そのデータが正しいかどうかを検証する仕組みをバリデーションといいます。
今回は以下のバリデーションを追加します。
Copied!- カードのタイトルの文字数が1文字以上255文字以下
- memoカラムの最大文字数が1000文字以下
app/models/card.rb
に以下のコードを追加してください。
app/models/card.rb12345678 Copied!class Card < ApplicationRecord
belongs_to :list
# ==========ここから追加==========
validates :title, length: { in: 1..255 }
validates :memo, length: { maximum: 1000 }
# ==========ここまで追加==========
end
length
は属性の値の長さを検証するメソッドです。
以上で今回のパートは終了です。
お疲れさまでした。