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

プラクティス > Docs一覧をVue.js化する #4293

Merged
merged 8 commits into from
Mar 10, 2022

Conversation

aim2bpg
Copy link
Contributor

@aim2bpg aim2bpg commented Feb 24, 2022

Issue: #4048

概要

プラクティス > Docs一覧をVue.js化して、非同期に読み込むようにしました。

参考PR

Refs: #3852 他、#3963,#3181,#2537,#2450,#2286,#2280,#2260 を参照しました。

変更点

差分が大量となるため、レビュー効率向上と自分の備忘録も兼ねて、概要を以下に、詳細を日報にまとめました。

  • Routing

    • routes/api.rbpractices/pages#indexアクションを追記。
  • Controller

    • APIのコントローラapp/controllers/api/practices/pages_controller.rbを追加(既存のapp/controllers/practices/pages_controller.rbを流用し、メソッド名の先頭にAPI::を付加、継承元もAPI::BaseControllerに変更)
    • 既存のapp/controllers/practices/pages_controller.rbより不要となった@pagesの代入部分を削除。
  • View

    • RoutingとControllerで追加したAPIのindexアクションに対応させるため、app/views/api/practices/pages/index.json.jbuilderを追加(app/views/api/pages/index.json.jbuilderを完全流用)
    • app/views/practices/pages/index.html.slimのVue.jsに置き換えたDocs一覧表示部分を削除し、Vue.jsのtemplateを埋め込むためのdiv要素を追記。
    • Vue.jsに置き換えられて不要となったHTMLのpageパーシャルapp/views/pages/_page.html.slimを削除。
  • vue読込用JS

    • app/javascript/packs/application.jsにコンパイル対象のJSファイルpractices-pages.jsを追記。
    • vueファイルを読み込むためのJSファイルapp/javascript/practices-pages.jsを追加(同階層のpages.jsを流用)
    • 上記ファイルに、既存のMenu > Docs一覧と表示処理を共通化させるために、practicesを親とするURLパスの一部を引数としてvueファイルに渡す記述を追記。
  • vue

    • 読込用JSからpracticesを親とするURLパスの一部を受け取って、Menuからでもプラクティスからでも同じvueファイルを使って表示できるように共通化するための記述をapp/javascript/pages.vueに追記。
  • テスト

    • APIのコントローラ用の機能テストtest/integration/api/practices_pages.test.rbを追加
  • 以上の詳細情報は「日報」を参照ください。

2022-03-11 追記

本PRを参考とされる方はご注意ください。
本PRでは、すでにVue.js化されたトップページ > Docs一覧とコードをどう共通化させるかが課題でした。他のVue.js化にそのまま当てはまらないかもしれません。ただ、ファイルごとにどのような修正が入るのかイメージするのには参考となるかもしれません。
また、上記修正後のレビューで「APIを増やさずにDocsのAPIにpracticeでの絞り込み機能を追加した方が良い」との助言があり、作ったAPIを削る修正をしていますので、Files changedの最終形をいきなり作ったわけではなく、そういう修正の経緯があったことをご承知の上で参考とされてください。

動作確認

demo

@aim2bpg aim2bpg force-pushed the feature/convert-practices-docs-lists-to-vuejs branch from c794d70 to 64f77df Compare February 24, 2022 08:47
@aim2bpg aim2bpg changed the title プラクティス > Docs一覧をVue.js化した プラクティス > Docs一覧をVue.js化する Feb 24, 2022
@aim2bpg aim2bpg marked this pull request as ready for review February 25, 2022 07:35
@aim2bpg
Copy link
Contributor Author

aim2bpg commented Feb 25, 2022

@garammasala29 さん、おつかれさまです。
類似Issueに着手されるようですので、変更点のインプットも兼ねてレビューをお願いいたします🙏
なお、テストで1つエラーとなるところがあるのですが、別Issue #4298 を立ててレビュー依頼中です。
マージされると、解消する見込みです。ご承知おきください🙇🏻‍♂️

Copy link
Contributor

@garammasala29 garammasala29 left a comment

Choose a reason for hiding this comment

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

@aim2bpg さん
お疲れ様です。レビュー依頼ありがとうございました!大変遅くなりすみません🙇‍♂️
手元でもVue化されることを確認できました。

default.mov

issueを作成された箇所以外のテストが通ることも確認できています。
日報で実装の意図などを丁寧に書かれていたので、内容をよく理解しながらレビューすることができました。LGTMです!

1点だけ気になる点があり、app/controllers/pages_controller.rb#indexでVue化に伴い不要なコードが見受けられ、どうしたらいいかなと考えていました。
@aim2bpg さんの今回の変更差分と関係ない部分ではありますが、少し気になったので記しておきます。

@aim2bpg
Copy link
Contributor Author

aim2bpg commented Mar 1, 2022

@garammasala29 さん、ご確認ありがとうございます🙇🏻‍♂️

1点だけ気になる点があり、app/controllers/pages_controller.rb#indexでVue化に伴い不要なコードが見受けられ、どうしたらいいかなと考えていました。

@practice = Practice.find(params[:practice_id])のことでしょうか?
こちらは、プラクティスのタイトルに関わる記述でしたので、削除するとエラーとなってしまいますので必要なコードという認識です。こちらのコードでない場合は、具体的に記載していただけますと幸いです😄

@garammasala29
Copy link
Contributor

@aim2bpg さん
お疲れ様です。
app/controllers/pages_controller.rb@pages = Page.with_avatar~~に関してのお話でした、practicesから生えていないものになります
(変更したファイルではないので、対象のコードに直接コメントができませんでした。分かりづらくすみません🙏)

@aim2bpg
Copy link
Contributor Author

aim2bpg commented Mar 2, 2022

@garammasala29 さん、ありがとうございます。
自分がファイルパスをよく見ておらずに誤解してました🙏

app/controllers/pages_controller.rb@pages = Page.with_avatar~~

上記の記述は、本Issueとは別ページの部品と思われますのでスコープ外とさせて下さい。

手元で上記の記述を削除してみると、たしかにDocs一覧ページも表示できましたし、テストもPassしました。
一見すると不要と思われるのですが、影響範囲を調べずに安易に削除してしまうと、意図せず表示が壊れたりする恐れもあるので、そのままでもよいかと考えました。

@aim2bpg aim2bpg requested a review from komagata March 2, 2022 02:16
@aim2bpg
Copy link
Contributor Author

aim2bpg commented Mar 2, 2022

@komagata さん、お手すきの際にレビューをお願いいたします🙏
なお、テストで1つエラーとなるところがあるのですが、別Issue #4298 を立ててレビュー依頼中です。
マージされると解消する見込みです。別Issue #4298 と合わせてご確認をお願いいたします🙇🏻‍♂️

@garammasala29
Copy link
Contributor

@aim2bpg さん

上記の記述は、本Issueとは別ページの部品と思われますのでスコープ外とさせて下さい。

全然問題ありません、大丈夫です。気になる部分でしたので、共有させていただいてよかったです。
ご確認いただきありがとうございました🙏

@aim2bpg aim2bpg force-pushed the feature/convert-practices-docs-lists-to-vuejs branch 2 times, most recently from 64accee to d294b83 Compare March 4, 2022 12:16
@aim2bpg
Copy link
Contributor Author

aim2bpg commented Mar 5, 2022

@machida さん
mainを取り込んだ際に、Vue.js化前後でテストでFailする点がもう1箇所あって、どちらの記述があるべき姿がわかりませんのでご教示いただきますでしょうかー
image

@machida
Copy link
Member

machida commented Mar 6, 2022

@aim2bpg 返信遅れてすいません。meta が付く方でお願いします。

ちなみに、付かない方のclassは

貼り付けた画像_2022_03_06_23_48

こっちの大きい方ようのclassですね。

それが間違えて使われているっぽいです。

@aim2bpg
Copy link
Contributor Author

aim2bpg commented Mar 6, 2022

@machida さん、metaの方で承知しましたー🙇🏻‍♂️
多分そうかなと思ったのですが、念の為にご確認させていただきました🙏

@aim2bpg aim2bpg force-pushed the feature/convert-practices-docs-lists-to-vuejs branch from d294b83 to 7ad8732 Compare March 6, 2022 22:24
@aim2bpg
Copy link
Contributor Author

aim2bpg commented Mar 6, 2022

@komagata さん、あらためましてレビュー依頼させていただきます〜🙏
Vue.js化後にテストが通らなくなった件 #4298 も解消しました。

@@ -0,0 +1,14 @@
# frozen_string_literal: true

class API::Practices::PagesController < API::BaseController
Copy link
Member

Choose a reason for hiding this comment

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

APIを増やすのではなく、DocsのAPIにpracticeでの絞り込み機能を追加することで対応できればと思います〜

https://github.com/fjordllc/bootcamp/blob/main/app/controllers/api/pages_controller.rb#L3

/api/pages?practice_id=1234のようなURLになるイメージ。

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ご提案ありがとうございます。おかげさまで、コードがスッキリしました〜😄

@aim2bpg aim2bpg force-pushed the feature/convert-practices-docs-lists-to-vuejs branch from c4947e8 to cf46d07 Compare March 9, 2022 12:06
@aim2bpg
Copy link
Contributor Author

aim2bpg commented Mar 9, 2022

@komagata さん、#4293 (comment) の修正をしましたので、ご確認をお願いいたします〜🙏
あと、DocsのAPIテストが入れてなかったので、今回追加しておきました。

@@ -27,6 +27,7 @@ export default {
page: page
},
props: {
practiceId: { type: String, required: true },
Copy link
Contributor

Choose a reason for hiding this comment

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

通常の docs 一覧ページのほうの js のコードでは practiceId を props として渡していないと思うので、required: true にしちゃうとそっちで warning になっちゃう気がしました。このへんです。

props: { selectedTag: selectedTag }

Screen Shot 2022-03-09 at 21 39 28

Copy link
Contributor Author

Choose a reason for hiding this comment

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

エラーが出ないからと、リファクタしたつもりが裏目に出てしまいました。
下記の元の記述に戻すことで、ワーニングが出ないことを確認しました。
practiceId: { type: String, default: '', required: false },

Comment on lines 7 to 21
if params[:practice_id]
practice = Practice.find(params[:practice_id])
@pages = practice.pages.with_avatar
.includes(:comments,
{ last_updated_user: { avatar_attachment: :blob } })
.order(updated_at: :desc)
.page(params[:page])
else
@pages = Page.with_avatar
.includes(:comments, :practice, :tags,
{ last_updated_user: { avatar_attachment: :blob } })
.order(updated_at: :desc)
.page(params[:page])
@pages = @pages.tagged_with(params[:tag]) if params[:tag]
end
Copy link
Contributor

Choose a reason for hiding this comment

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

params[:practice_id] があるときもないときもベースになるクエリはほとんど変わらないと思うので、プラクティスによる絞り込みだけ conditional にやるのが良いのではと思いました 💡 Kaminari の page による絞り込みは先にあって良いのかちょっとわからなかったので、そのへんは調査してみてもらえると〜 🙏

Suggested change
if params[:practice_id]
practice = Practice.find(params[:practice_id])
@pages = practice.pages.with_avatar
.includes(:comments,
{ last_updated_user: { avatar_attachment: :blob } })
.order(updated_at: :desc)
.page(params[:page])
else
@pages = Page.with_avatar
.includes(:comments, :practice, :tags,
{ last_updated_user: { avatar_attachment: :blob } })
.order(updated_at: :desc)
.page(params[:page])
@pages = @pages.tagged_with(params[:tag]) if params[:tag]
end
@pages = Page.with_avatar
.includes(:comments, :practice, :tags,
{ last_updated_user: { avatar_attachment: :blob } })
.order(updated_at: :desc)
.page(params[:page])
@pages = @pages.where(practice_id: params[:practice_id]) if params[:practice_id]
@pages = @pages.tagged_with(params[:tag]) if params[:tag]
end

Copy link
Contributor Author

Choose a reason for hiding this comment

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

こちらもご提案ありがとうございます🙏コードがスッキリしました😄
page絞り込みが先にあっても違和感なく動作することを確認しました。

Comment on lines +6 to +14
test 'GET /api/pages.json' do
get api_pages_path(format: :json)
assert_response :unauthorized

token = create_token('kimura', 'testtest')
get api_pages_path(format: :json),
headers: { 'Authorization' => "Bearer #{token}" }
assert_response :ok
end
Copy link
Contributor

Choose a reason for hiding this comment

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

practice_id による絞り込みや tag による絞り込みのテストもあると better だと思うけど omakase です〜。

Copy link
Contributor Author

Choose a reason for hiding this comment

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

たしかに、practice_id による絞り込みは実装してますのでテスト追加しました。
tagの方は、Vue.js化されていませんので対象外としています。

Copy link
Contributor

Choose a reason for hiding this comment

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

今回の PR の範囲で言うとそうだと思うんですが、API 単体の仕様としてはタグでの絞り込みができる、かつここは API に対するテストを書く場所なので、仕様があるならそれを確認するテストもここにあるべきだと思いました。そしてこの機能は、通常の Docs の一覧のほうで使われていそう (タグ一覧からタグで絞り込める) です。ただ、この PR の作業範囲としてどこまでのテストの追加を含めるかというのはまた別の話なので、その点は引き続きおまかせです!

@aim2bpg
Copy link
Contributor Author

aim2bpg commented Mar 9, 2022

@cafedomancer さん、ご提案ありがとうございました。
修正完了しましたので、ご確認いただけますと幸いです🙏

Comment on lines +6 to +14
test 'GET /api/pages.json' do
get api_pages_path(format: :json)
assert_response :unauthorized

token = create_token('kimura', 'testtest')
get api_pages_path(format: :json),
headers: { 'Authorization' => "Bearer #{token}" }
assert_response :ok
end
Copy link
Contributor

Choose a reason for hiding this comment

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

今回の PR の範囲で言うとそうだと思うんですが、API 単体の仕様としてはタグでの絞り込みができる、かつここは API に対するテストを書く場所なので、仕様があるならそれを確認するテストもここにあるべきだと思いました。そしてこの機能は、通常の Docs の一覧のほうで使われていそう (タグ一覧からタグで絞り込める) です。ただ、この PR の作業範囲としてどこまでのテストの追加を含めるかというのはまた別の話なので、その点は引き続きおまかせです!

Comment on lines 16 to 25
test 'GET /api/practices/315059988/pages.json' do
practices = practices(:practice1)
get api_pages_path(practices.id, format: :json)
assert_response :unauthorized

token = create_token('kimura', 'testtest')
get api_pages_path(practices.id, format: :json),
headers: { 'Authorization' => "Bearer #{token}" }
assert_response :ok
end
Copy link
Contributor

Choose a reason for hiding this comment

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

あれ、なんか test の説明がおかしそう...? practice_id は query string に入るはず。

Copy link
Contributor Author

Choose a reason for hiding this comment

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

たしかに〜😇 /api/pages.json?practice_id=315059988に修正しました🙏

@@ -27,6 +27,7 @@ export default {
page: page
},
props: {
practiceId: { type: String, default: '', required: false },
Copy link
Contributor

Choose a reason for hiding this comment

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

default が空文字になっているのは、あんまり意味を成していないような気がしました。値が入っていないことを表現したいのであれば nullundefined を使う、もしくは props を渡さないときは practiceId がそのように設定されるという挙動に任せておく、のどちらかが良いと思います。

Copy link
Contributor Author

Choose a reason for hiding this comment

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

reports.vuenullが使われていたので、pagesでもnullを使用しました。

@aim2bpg
Copy link
Contributor Author

aim2bpg commented Mar 10, 2022

@cafedomancer さん、ご指摘ありがとうございました🙇🏻‍♂️
APIのDocs一覧でタグによる絞り込みについても、テスト追加しております。
お手すきの際に、ご確認をお願いいたします🙏

@aim2bpg
Copy link
Contributor Author

aim2bpg commented Mar 10, 2022

@cafedomancer さん、ご確認ありがとうございました🙇🏻‍♂️ 初めてレビューしていただいて勉強になりました〜

@komagata さん、#4293 (comment) につきまして、修正しましたのでご確認をお願いいたします〜🙏

Copy link
Member

@komagata komagata left a comment

Choose a reason for hiding this comment

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

確認しました、OKですー🙆‍♂️

@komagata komagata merged commit 31249a3 into main Mar 10, 2022
@komagata komagata deleted the feature/convert-practices-docs-lists-to-vuejs branch March 10, 2022 18:16
@github-actions github-actions bot mentioned this pull request Mar 10, 2022
32 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants