fjordllc / bootcamp

プログラマー向けEラーニングシステム
https://bootcamp.fjord.jp
MIT License
286 stars 71 forks source link

メンターダッシュボードに表示しているn日経過の提出物一覧を非vue化したい。 #7947

Open machida opened 4 months ago

machida commented 4 months ago

メンターでログインしたときにダッシュボードに表示されるこれが今はVueで実装されているので、Railsのviewに移行する。

貼り付けた画像_2024_07_09_20_02
Shrimprin commented 2 months ago

📝 関連するPR

Shrimprin commented 1 month ago

@komagata @machida お疲れ様です。 本イシューでは既存のVueをRailsのViewComponentへ置き換えをしています。 ViewCompoentのテストの実装で上手くいかない点があり、アドバイスをいただけますでしょうか 🙇 (※2024/9/30 18:50 エラー内容、エラーが発生するパターンを少し修正しました)

解決したいこと

ViewComponentのテストでActiveDecoratorメソッドがundefined methodエラーとなる。 (以下、ViewComponentのテスト = コンポーネントテストActiveDecoratorメソッド = デコレーターメソッドと記載します)

エラー内容

例えば、ViewComponentのhtmlファイルでuser.icon_titleを呼び出す部分で以下のようなエラーが発生する。 (エラーの発生するテストコードはまだPRには含めていません) エラーが発生するのはコンポーネントテストから呼び出した時のみで、テスト以外(ブラウザから呼び出す)はエラーは発生しない。

❯ rails test test/components/product/product_component_test.rb
Running via Spring preloader in process 11715
Run options: --seed 21297

# Running:

....E

Error:
Products::ProductComponentTest#test_render_comments_count_when_there_are_comments:
NoMethodError: undefined method `icon_title' for #<User id: ...
...
{中略}
...
    app/components/products/product_component.html.slim:71:in `block in call'
    app/components/products/product_component.html.slim:69:in `call'
    test/components/product/product_component_test.rb:67:in `test_render_comments_count_when_there_are_comments'

rails test test/components/product/product_component_test.rb:64
全文 ``` bash ❯ rails test test/components/product/product_component_test.rb Running via Spring preloader in process 11715 Run options: --seed 21297 # Running: ....E Error: Products::ProductComponentTest#test_render_comments_count_when_there_are_comments: NoMethodError: undefined method `icon_title' for # app/components/products/product_component.html.slim:71:in `block in call' app/components/products/product_component.html.slim:69:in `call' test/components/product/product_component_test.rb:67:in `test_render_comments_count_when_there_are_comments' rails test test/components/product/product_component_test.rb:64 ```

調べたこと

ActiveDecorator

ViewComponentのテストでのActiveDecoratorの利用

エラーが発生するパターン

以下のように、コンポーネントテストでデコレーターを適用したuserproductcommentを作成した後、html側でcommentからuserを取得してデコレーターメソッドを呼び出そうとすると、undefined methodとなる。

https://github.com/fjordllc/bootcamp/blob/56997a823c7a36bc5230cfce1ee5a28d4f24c85b/app/components/products/product_component.html.slim#L69-L71

対応方法

対応方法を検討しましたのでご助言お願いできますでしょうか。

  1. ViewComponentのロジック部分とActiveDecoratorはモデルとビューをスリムにするためにロジックを記述する場所という役割が被っているという認識です。ViewComponentではデコレーターメソッドは使わずにコンポーネントのロジック部分に代わりにそのロジックを記述すべきなのでしょうか?
  2. システムテストでは明示的にextend(HogeDecorator)でデコレーターを適用しないでもデコレーターメソッドが利用できます。コンポーネントテストでも同様のことが可能なのであればその方法をご教授いただけますでしょうか?

以上、お手数ですがご回答をお願いいたします。

komagata commented 1 month ago

@Shrimprin

  1. ViewComponentのロジック部分とActiveDecoratorはモデルとビューをスリムにするためにロジックを記述する場所という役割が被っているという認識です。ViewComponentではデコレーターメソッドは使わずにコンポーネントのロジック部分に代わりにそのロジックを記述すべきなのでしょうか?
  2. システムテストでは明示的にextend(HogeDecorator)でデコレーターを適用しないでもデコレーターメソッドが利用できます。コンポーネントテストでも同様のことが可能なのであればその方法をご教授いただけますでしょうか?

2でお願いします。もうちょっとだけ調べてみてください〜

Shrimprin commented 1 month ago

@komagata お疲れ様です! Active Recordのafter_findコールバックを使ってデコレーターを適用するヘルパーを作成して、問題を対処できるようにしました。 以下のような実装方針で良いかご助言お願いできますでしょうか。

class Products::ProductsComponentTest < ViewComponent::TestCase def setup DecoratorHelper.auto_decorate(User) # デコレーターを適用したいモデルを引数で渡す

その他の処理

end

テスト

end



これにより`User`レコードを読み込むたびにデコレーターが適用され、テスト内で毎回`extend(UserDecorator)`しなくて済みます。

### 参考
- [Railsガイド after_initializeとafter_find](https://railsguides.jp/active_record_callbacks.html#after-initialize%E3%81%A8after-find)
komagata commented 1 month ago

いいと思います。ただ下記に似たコードがあるので何かしら共通化できるといいかもですね。

bootcamp/test/active_decorator_test_case.rb at main · fjordllc/bootcamp

Shrimprin commented 1 month ago

@komagata ありがとうございます。 共通化も含めてPRを作成していきます。