Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/#34 add tags to memos #79

Merged
merged 50 commits into from
Sep 27, 2024
Merged

Conversation

nova818
Copy link
Collaborator

@nova818 nova818 commented Aug 17, 2024

対応するissue

対応内容

  • フォームオブジェクトを作成
  • メモの作成&更新時にタグが紐づけられるようmemoのコントローラーを修正
  • フォームオブジェクトのテストコードを追加
  • memoのコントローラーの修正に伴うテストコード修正

@nova818 nova818 self-assigned this Aug 17, 2024
@nova818 nova818 added the backend バックエンドのissues label Aug 17, 2024
@nova818 nova818 marked this pull request as ready for review August 17, 2024 12:08
Copy link
Contributor

@kakeru-one kakeru-one left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nova818
一旦テスト以外で気になったところをコメントしました!

backend/app/controllers/memos_controller.rb Outdated Show resolved Hide resolved
backend/app/controllers/memos_controller.rb Outdated Show resolved Hide resolved
backend/app/controllers/memos_controller.rb Outdated Show resolved Hide resolved
backend/app/forms/memo_form.rb Outdated Show resolved Hide resolved
backend/app/forms/memo_form.rb Outdated Show resolved Hide resolved
backend/app/controllers/memos_controller.rb Outdated Show resolved Hide resolved
backend/app/forms/memo_form.rb Outdated Show resolved Hide resolved
backend/app/forms/memo_form.rb Outdated Show resolved Hide resolved
backend/app/forms/memo_form.rb Outdated Show resolved Hide resolved
backend/app/forms/memo_form.rb Outdated Show resolved Hide resolved
Copy link
Contributor

@kakeru-one kakeru-one left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nova818
コメントしました!
前回よりかなりコードが整理されてきましたね! 🎉

@@ -16,22 +16,24 @@ def show

# POST /memos
def create
memo = Memo.new(memo_params)
if memo.save
memo_form = Memo::BuildForm.new(params: create_params)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO/Simple

formで伝わるかなと思います!

Suggested change
memo_form = Memo::BuildForm.new(params: create_params)
form = Memo::BuildForm.new(params: create_params)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

確かにmemoつけなくて良さそうですね🙆‍♂️

end
end

# PUT /memos/:id
def update
memo = Memo.find(params[:id])
memo_form = Memo::UpdateForm.new(params: update_params, memo: memo)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

こちらも同上です!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

併せて修正します🫡

end

def update_memo_params
params.require(:memo).permit(:content)
def update_params
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rikuya98 @nova818
[仕様の確認]

メモはタイトルの更新はできない、でいいんでしたっけ?
(zennとかQiitaとか、esaとかだとtitleも更新できる)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ochi-sho-private-study @nova818
僕が作成した時のissue見返したら
title更新できない仕様の指定がありました!(当時そこまで深く考えてなかったので、理由までは聞いてませんが💦)

#26

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

タイトルも更新可能にすることになったかと思いますので、そのような認識で進めます!


attr_reader :params

validate :memo_valid?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Must

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cascadeバリデーターを利用する形に修正します!
ただ、実力不足からcascadeバリデーターのコードで詳細に理解できていない部分があり、引き続きコードリーディングを進めます...😢

@params = params
end

def memo
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Must

このメソッドは外部に公開する必要はありますか?
みたところその必要性はなさそうですので、privateメソッドでいいと思いました!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

確かに、memoはクラス内部でのみ仕様されるメソッドですね💦
privateメソッドに変更します🙆‍♂️

let(:params) { { title: 'Test Memo', content: 'This is a test memo', tag_ids: tag_ids } }
let(:memo_build_form) { described_class.new(params: params) }

specify 'メモが新規作成されること' do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO

MemoTagのカウントも確認したいです!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MemoTagのカウントを確認するコードを追加します🙆‍♂️

let(:memo_build_form) { described_class.new(params: params) }

specify 'メモが新規作成されないこと' do
expect { memo_build_form.save }.not_to(change(Memo, :count))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TagMemoのカウントも確認したいです!

expect do
post '/memos', params: { memo_form: invalid_memo_form_params }, as: :json
end.not_to change(Memo, :count)
end.not_to change(Tag, :count)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question

Tagではなく、MemoTagの個数を確認するべきではないでしょうか? 🤔

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MemoTagの個数を確認すべきですね。なんでタグの数を確認したんだろう...笑
確認不足でした💦 修正します🙏

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BuildFormでコメントしたことを参考にして、修正してみて欲しいです!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

承知しました!詳細なコメントありがとうございます🙇‍♂️

end

describe '#update' do
context 'フォームの値が有効な場合' do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

既存のmemo.memo_tagsが存在する場合もテストしたいです!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

こちら、テストの冒頭書き部分で既存のmemo_tagsを作成していたため、既存のmemo.memo_tagsが存在する場合のテストはできているのかなと考えていたのですが、下記とは別に改めてテストケースを追加した方が良いということでしょうか?🤔

before { create(:memo_tag, memo:, tag:) }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

すみません、こちらは対応不要ですね 💦

@kakeru-one kakeru-one changed the base branch from feature/#33-add-tags-api to main September 12, 2024 09:18
Copy link
Contributor

@kakeru-one kakeru-one left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nova818
コメントしました

Copy link
Contributor

@kakeru-one kakeru-one Sep 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO

memo_tags_to_removeとmemo_tags_to_addの部分が、
作成される部分と削除される部分の処理が追いづらいので、以下のように修正するといいと思います。

# frozen_string_literal: true

class Memo
  class UpdateForm
    include ActiveModel::Validations

    validates :memo, cascade: true
    validates :memo_tags, cascade: true, if: -> { errors.empty? }

    def initialize(params:, id:)
      @params = params
      @id = id
    end

    def save
      return false if invalid?

      ActiveRecord::Base.transaction do
        save_record!(memo)
        memo.memo_tags.select(&:marked_for_destruction?)
                      .each { destroy_record!(_1) }
      end

      errors.empty?
    end

    private

    attr_reader :params, :id

    def save_record!(record)
      return true if record.save

      errors.add(:base, record.error_message)
      raise ActiveRecord::Rollback
    end

    def memo
      @memo ||= \
        Memo.find(id)
            .tap do |model|
              model.assign_attributes(
                title: params[:title],
                content: params[:content],
                tags: tags
              )
            end
    end

    def destroy_record!(record)
      return true if record.destroy

      errors.add(:base, record.error_message)
      raise ActiveRecord::Rollback
    end

    def memo_tags
      @memo_tags ||= memo.tap do |model|
        mark_for_destruction_memo_tags!
      end.memo_tags.reject(&:marked_for_destruction?)
    end

    def tag_ids = params[:tag_ids] || []

    def tags = Tag.where(id: tag_ids)

    def before_save_tag_ids
      @before_save_tag_ids ||= memo.memo_tags.pluck(:tag_id)
    end

    def destroy_target_tag_ids = before_save_tag_ids - tag_ids

    def mark_for_destruction_memo_tags!
      memo.memo_tags.each do |memo_tag|
        next unless destroy_target_tag_ids.include?(memo_tag.tag_id)

        memo_tag.mark_for_destruction
      end
    end
  end
end

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

改善案の提示ありがとうございます🙇‍♂️
上記案に沿って修正を進めます。

Comment on lines 42 to 43
title: params[:title] || model.title,
content: params[:content] || model.content,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Must

フロントからは何も編集フォームを入力しなければ、
params[:hoge]がnilではなく、createしたときの値のままでリクエストされるはずなので、この処理はおかしいと思います。

Suggested change
title: params[:title] || model.title,
content: params[:content] || model.content,
title: params[:title],
content: params[:content],

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

フロントからは何も編集フォームを入力しない場合、params[:hoge]がnilになると思い込んでいました💦
修正します。

Copy link
Contributor

@kakeru-one kakeru-one left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nova818
コメントしました!

def memo_params
params.require(:memo).permit(:title, :content, :poster)
def form_params
params.require(:form).permit(:title, :content, :poster, tag_ids: [])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Idiomatic

memoに関するものなので、memoをtopレベルのkeyとするようにしましょう!

Suggested change
params.require(:form).permit(:title, :content, :poster, tag_ids: [])
params.require(:memo).permit(:title, :content, :poster, tag_ids: [])

@@ -45,7 +47,7 @@ def destroy

private

def memo_params
params.require(:memo).permit(:title, :content, :poster)
def form_params
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO/Readable

memo_paramsのままにしておきましょう!

end
end

# PUT /memos/:id
def update
memo = Memo.find(params[:id])
# memo = Memo.find(params[:id])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

このコメントは不要なので消しましょう!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

こちら確認不足でした💦 余計な負担をお掛けしてしまい申し訳ありませんでした🙇‍♂️

Copy link
Contributor

@kakeru-one kakeru-one left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@kakeru-one kakeru-one merged commit 1d6d9fb into main Sep 27, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend バックエンドのissues
Projects
None yet
Development

Successfully merging this pull request may close these issues.

メモのタグをメモの作成・更新時に登録できるようにする
3 participants