0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

DB設計を改修する~Model編~

Last updated at Posted at 2022-08-01

はじめに

Q&Aアプリを作成しています。DB設計で改修が必要になったので記事にしました。
今回はモデルの関連付けを解消します。

改修前のDB設計

Qiita構想前.png
msg.jpeg

【解答】
質問(Question)に対して、最初に投稿(アソシエーション)されたCommentのオブジェクト
【コメント】
解答に対して、投稿(アソシエーション)されたCommentのオブジェクト

ややこしい!

改修後のDB設計(予定)

Qiita構想後.png
解答をAnswerテーブル、コメントをCommentテーブルに分けます。
こちらの方が管理しやすいコードだと思います。特定の質問の解答やコメントを取得するのも簡単です。
Answerテーブルで解答機能を実装できるまで、UserテーブルとQuestionテーブルはCommentテーブルの関連付けを解消します。

関連付けを解消する前に


開発環境のDBにCommentのオブジェクトがあるのでリセットします。

rails db:migrate:reset


Commentのサンプルデータは不要なので削除します。(この記事ではコメントアウト)

db/seeds.rb
# other = User.last
# questions = User.first.questions.order(:created_at).take(6)
# 5.times do
#   user_id = other.id
#   content = Faker::Lorem.sentence(word_count: 3)
#   questions.each { |question| question.comments.create!(user_id: other.id,
#                                                         content: content) }
# end


データを投入します。Commentのデータが生成されていないことを確認できました。

rails db:seed

関連付けの解消

has_many

あるUserとCommentはhas_many(1対多)の関係性
あるQuestionとCommentはhas_many(1対多)の関係性  
has_manyをコメントアウトにします。

app/models/user.rb
class User < ApplicationRecord
    has_many :questions, dependent: :destroy
  # has_many :comments,  dependent: :destroy
end
app/models/question.rb
class Question < ApplicationRecord
  # has_many   :comments, dependent: :destroy
end

belongs_to

あるCommentはUserとbelongs_to(1対1)の関係性
あるCommentはQuestionとbelongs_to(1対1)の関係性
belongs_toをコメントアウトにします。関連付けのバリデーションも不要です。

app/models/comment.rb
class Comment < ApplicationRecord
#   belongs_to :user
#   belongs_to :question

#   validates(
#           :user_id,
#           presence: true
#   )

#   validates(
#           :question_id,
#           presence: true
#   )
end

テスト

これで関連付けは解消されました。(既存の)テストで確認してみます。

require 'rails_helper'

RSpec.describe Comment, type: :model do
  let(:other)    { FactoryBot.create(:user) }
  let(:question) { FactoryBot.create(:question) }
  let(:comment)  { question.comments.build(user_id: other.id,
                                           content: "Example content")}
  it "有効であること" do
    expect(comment).to be_valid
  end
end

テストを実行。ちゃんと失敗しました。関連メソッドが使えないようになりました。
無事、関連付けが解消できました!!!

NoMethodError:
       undefined method `comments' for #<Question id: 3131, ~~~~

あとがき

DB設計は本当に大切だと認識させられました!アプリ開発がまだ序盤の方で助かりました
あと、テストはできる限り先に書きましょう!テストが無いと、他のDBデータや機能に影響が出てしまっていないか確認するのが困難になります。(先に書いてて良かった.....)  
これからルーティング、コントローラ、ビューを改修していきます。これらについても記事にしていく予定です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?