-
Notifications
You must be signed in to change notification settings - Fork 71
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
Userが複数のroleを持てるように変更 #3979
Userが複数のroleを持てるように変更 #3979
Conversation
@machida PRのdescriptionに載せたスクリーンショットの場所(複数roleを持つユーザーの、ユーザー詳細画面の区分欄)のみ見た目が変わっています。お手すきのときに確認お願いいたします🙇♂️ |
@naomichi-h 複数入るようにマークアップを変更しましたー |
@machida 対応ありがとうございます! @AudioStakes こちらのレビューをお願いできますでしょうか? |
@naomichi-h 複数の role を持つユーザーの class 属性について現在の PR の変更においては、たとえば次のように
これについて、 そのため、class 属性に設定する role は「どれか1つのみ」もしくは「複数の role すべて」のどちらなのか教えてもらいたいです。 また、それぞれの場合について、以下の質問があります。 「どれか1つのみ」の場合その1つの role は常に一定に(常に同じ role が選ばれるように)する必要がありますか? 「複数の role すべて」の場合お互いに干渉し合う role(たとえば CSS で指定されている色が異なる、など)の場合、どの role を優先するのでしょうか(そのような規則がすでにあるのでしょうか)? |
@AudioStakes 質問ありがとうございます🙇♂️
どれか一つのみです❗️ 本PRでは、今回の変更による影響を最小限に抑えるため、「ユーザー詳細の区分欄以外は全て、変更前と同じroleが出力される」ことを目指しています。 つまり、複数のroleをもつユーザーに設定するclass属性は、「変更前の 変更前の 今回、userが複数roleを持てるように変更をしたのですが、
|
@naomichi-h |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
修正内容について確認しました!
期待どおりの振る舞いになっていますので、基本的には OK です👍
改善できそうなところはコメントしましたので、ご確認お願いしますー
修正する場合は修正後に改めてレビュー依頼をお願いします🙏
[:student] | ||
else | ||
roles.select { |v| v[:value] }.map { |h| h[:role] } | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
※ UserDecorator#role
にコメントしたつもりだったのですが、位置がずれてしまいました🙇♂️
2つほど改善できそうなところがあったのでコメントしますー
どちらも「必ず修正してほしい」という意図はありません。もし改善されていると実感できるようであれば、修正してみてもらえたらと思いますー🙏
改善案1
UserDecorator#role
について、修正前後の返り値が「最初に条件に当てはまった role 」から「条件に当てはまる role すべて」に変わっていますね。
この変更に伴って、修正が必要となる View 関連のファイルが多数生じている(すなわち影響範囲が大きい)ため、 UserDecorator#role
の返り値は変えない方がよいかもしれません。
代替案として、UserDecorator#role
はそのままにして、「条件に当てはまる role すべて」を返す UserDecorator#roles
を追加するという案があります。
UserDecorator#roles
の処理の中身は、今の修正後の UserDecorator#role
そのままです。
次のようなイメージです。
module UserDecorator
~省略~
def role
roles = [
{ role: :admin, value: admin },
{ role: :mentor, value: mentor },
{ role: :adviser, value: adviser },
{ role: :trainee, value: trainee },
{ role: :graduate, value: graduated_on },
{ role: :student, value: true }
]
roles.detect { |v| v[:value] }[:role]
end
def roles
roles = [
{ role: :admin, value: admin },
{ role: :mentor, value: mentor },
{ role: :adviser, value: adviser },
{ role: :trainee, value: trainee },
{ role: :graduate, value: graduated_on }
]
if student? && !graduated?
[:student]
else
roles.select { |v| v[:value] }.map { |h| h[:role] }
end
end
~省略~
end
UserDecorator#roles
を追加した後に、次の app/views/users/_metas.html.slim
の user.role.each
を user.roles.each
に変更することで、ユーザー詳細画面の区分欄には今の修正後のとおり複数の role を表示できます。
bootcamp/app/views/users/_metas.html.slim
Lines 68 to 70 in 38733b2
- user.role.each do |role| | |
li | |
= t "target.#{role}" |
これにより、それ以外(ユーザー詳細画面の区分欄以外)は View まわりのコードを修正しなくて済むようになるので、このような実装にしてもよさそうですー
改善案2
初めて UserDecorator#role
の処理を見たとき、どんな値が返ってくるか少し考える必要がありました。
※ 同様に、UserDecorator#role
に基づいて実装された UserDecorator#roles
も少し考えました。
そのため、UserDecorator#role
(と UserDecorator#roles
) はもう少しわかりやすくできるかもしれません。
僕の改善案としては、以下のようにすると返り値が少しわかりやすくなるかもしれないなと思いました。
def role
return :admin if admin?
return :mentor if mentor?
return :adviser if adviser?
return :trainee if trainee?
return :graduate if graduated_on?
:student
end
def roles
roles = []
roles << :admin if admin?
roles << :mentor if mentor?
roles << :adviser if adviser?
roles << :trainee if trainee?
roles << :graduate if graduated_on?
roles << :student if roles.empty?
roles
end
※ 個人的にはもっとわかりやすくできそうな気がしています😅
もしより良い案がありましたら、そちらを選んでもらえたらと思いますー👍
追記
UserDecorator#role
は以下のようにした方が簡潔で良いかもしれないな、と思いましたー
def role
roles.first
end
※ UserDecorator#roles
は既存の UserDecorator#role
と優先順位が同じになるようにして配列を返しているつもりです(何か見落としているかもしれません)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
改善できそうなところをもう1つ見つけたので、お伝えしますー🙏
改善案3
複数の role を持つユーザーを例に考えると、既存の UserDecorator#role
が返す値は「複数の role の中で最も優先順位の高い role 」と捉えることができると思います。
それを表すために、メソッド名をUserDecorator#primary_role
に変更すると良いかもしれません。
この変更により UserDecorator#role
を使っている箇所のメソッド名を変更する必要が生じるものの、 role の用途に応じて user.primary_role
と user.roles
を使い分けしやすくなり、コードの読み手にもその意図が伝わりやすくなると思うので、このような実装にしても良さそうですー
1c44640
to
400969f
Compare
@AudioStakes たくさんの改善案ありがとうございます😊 たしかに!と思う部分が多数あったため、全面的に取り入れ、以下のように修正しました。
お手数ですが、確認をお願いいたします🙏 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@naomichi-h
ありがとうございます、修正内容を確認しました!
関数名について気づいたことをコメントしましたので、ご確認お願いしますー🙏
それ以外はOKです👍
追記
この PR の Assignees に、 naomichi さんがアサインされていないようですー
app/javascript/comments.vue
Outdated
roleAdmin: function () { | ||
return this.currentUser.roles.includes('admin') | ||
}, | ||
roleAdviser: function () { | ||
return this.currentUser.roles.includes('adviser') | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
関数 roleAdmin
と roleAdviser
はどちらも Boolean 型の値( true
or false
)を返していますね。
そのような関数には isHoge
や hasFuga
のように命名することが多いです。
roleAdmin: function () { | |
return this.currentUser.roles.includes('admin') | |
}, | |
roleAdviser: function () { | |
return this.currentUser.roles.includes('adviser') | |
} | |
isAdmin: function () { | |
return this.currentUser.roles.includes('admin') | |
}, | |
isAdviser: function () { | |
return this.currentUser.roles.includes('adviser') | |
} |
JavaScript の命名規則の参考資料を見つけられなかったため、代わりに bootcamp アプリ内のコードを例に示しますと以下のような関数があります
bootcamp/app/javascript/reports.vue
Lines 75 to 77 in 400969f
isUncheckedReportsPage() { | |
return location.pathname.includes('unchecked') | |
}, |
bootcamp/app/javascript/answers.vue
Lines 97 to 99 in 400969f
hasCorrectAnswer: function () { | |
return this.answers.some((answer) => answer.type === 'CorrectAnswer') | |
}, |
それぞれの関数名を一括で置換して対応できると思いますので、修正をお願いできますでしょうか🙏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
関数 roleAdmin と roleAdviser はどちらも Boolean 型の値( true or false )を返していますね。
そのような関数には isHoge や hasFuga のように命名することが多いです。
おお〜、そうなのですね!ありがとうございます😊いや本当に勉強になります✨
提案いただいた内容で修正しましたので、確認をよろしくお願いいたします🙏
95a5ce3
to
8fcc8f5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@naomichi-h
確認しました、OKですー👍
修正対象のファイル数が多くて修正に手間がかかったかもしれませんが、改善案を取り入れていただきありがとうございます😄
@AudioStakes こちらこそ、多くの修正をみていただいてありがとうございました 😊 @AudioStakes さんにお願いしてよかったです✨ @komagata こちらチームメンバーのレビュー通過しましたので、お手隙のときに確認をよろしくお願いいたします🙇♂️ |
app/javascript/comments.vue
Outdated
isAdmin: function () { | ||
return this.currentUser.roles.includes('admin') | ||
}, | ||
isAdviser: function () { | ||
return this.currentUser.roles.includes('adviser') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
共通の処理はmixinにすると良いかもです〜
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
二つの処理をisRole()としてまとめました!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@naomichi-h mixinはVue.jsの仕組みとして存在するmixinのことです〜
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
完全に勘違いしていました...😓
mixin使ってisRole
メソッドをファイルに分離しました!
@komagata 修正を行いましたので、ご確認お願いいたします🙏 |
3a67e29
to
994c126
Compare
app/models/notification.rb
Outdated
duplicates = scope.inject(Notification.all) { |notifications, scope_item| notifications.where(scope_item => self[scope_item]) } | ||
duplicates.where.not(id: id) | ||
end | ||
|
||
def self.product_update(product, receiver) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rubocopにて
Lint/IneffectiveAccessModifier: private (on line 265) does not make singleton methods private. Use private_class_method or private inside a class << self block instead.
と警告が出ていたため、self.product_update
をprivate外に出しました。
(警告通りにprivate_class_method
などを使ってself.product_update
をprivate化してしまうと、NoMethodErrorが発生し、products_test:23
でエラーになってしまうためです。)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#4103
の内容をpullしました!(修正方法は同様)
@komagata 修正とコメントをしましたので、確認のほどよろしくお願いいたします🙏 |
app/javascript/is-role.js
Outdated
@@ -0,0 +1,7 @@ | |||
export default { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mixin名がis-roleだとこのメソッド一つ限定になっちゃうのでroleとか広い意味の方がいいかもです〜
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
なるほど、たしかに今後role関係のメソッドを切り出したりすることを考えると、広い意味の方が良いですね😄
mixin名をroleに変更します!
- UserDecorator#rolesを追加 - UserDecorator#rolesを提案されたものに変更 - UserDecorator#roleをUserDecorator#primary_roleとし、中身を`roles.first`に変更
07b7217
to
54f52f5
Compare
@komagata 修正とコメントをしましたので、確認のほどよろしくお願いいたします🙏 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
確認しました、OKですー🙆♂️
@komagata これがチーム開発最後のマージとなりました✨ ありがとうございました!! |
@naomichi-h うお〜、お疲れ様です〜!開発ありがとうございました〜!! |
issue: #3930
ユーザーにroleを複数もたせられるようにした場合の影響範囲の調査
調査方法:
.role
で全ファイル検索を行い、ヒットしたファイルについてひとつずつ確認した。結果:以下の機能、ページに関係する
実施内容
User#roleの変更
bootcamp/app/decorators/user_decorator.rb
Line 16 in 54c4b6d
にて、複数のroleを持てるように変更。studentのみ、Userテーブルに単体でstudentだと判別できる属性がなかったため、
User#student?
を使用。User#student?
のみだとgraduate_onがtrueなUserもstudent扱いになってしまうため、if student? && !graduated?
とした。また、この変更により、変更前は
User.role
とすると、roleに応じたsymbolが返されていたが、変更後は、roleに応じた配列が返されるようになっている。各影響範囲内の機能、ページの変更
現状、
User.role
としたときに配列を返すと不具合が生じる。そこで、修正前と同じ値が返るよう、User.role
を用いるページのほとんどをUser.role[0]
とした。スクリーンショット
ほとんどの画面は変更前と変わらないが、ユーザー詳細画面の区分欄のみ、複数のroleを表示するように変更した。
変更前
変更後