ViewをもっとDRYにするために
この間開発しているサービスのリファクタリングを始めていた、
Best practiceもいろいろさがしたが、おもにhelperをつかってViewの再利用性を高めろてことだった
まあー、実際にためしてみようか
構成
Rails::View + Slim + Rails::Helpers + Rails::Partial
とくにほかのフレームワークはいれたくない最低限の状態からどれぐらいできるかの検証である
主に、三つもパターンが思いついたので検証と実用性を見てみる
主に再利用される部分の整理を着目する
- Helperに全部よせる
- Partialに全部よせる
- HelperとPartialを合わせて利用する
ViewHelper
# Helper.rb
module Test
def form message
content_tag :div, class: 'body' do
concat message
end
end
end
// View.slim
.html
= form @message
見た目的には問題ないようだが、問題ありありだった
# NG
def Test messages
Content_tag :div do
concat 'hi'
mesages.each do |m|
concat li_tag m
end
end
end
ループで、親のタグに着くと思われると思うが期待通りの動きはしない
each
にreturn
するだけで親にはreturn
してない問題点があると思ってreturn追加して見てもタメ
解決はloopを外に持ち出して、変数に割り当てる
実用性
HelperでDRYにはなるが、このコード見てrenderされてタグがイメージできる?
実用性ほぼ皆無
Partial
// View.slim
.html
- @params.each do |param|
= render partial: 'view/test', locals { param: param}
// view/_test.slim
.body
= param.message
なかなか、部分的に分けられて見た目もよくなったな
部分的にする事で、親のファイルが膨大に慣れない
でも、@value
とかが散らばっているな
どこでどれが宣言されているかもわかりずらいしな
検証
なかなかいいやり方だし、部分的にすることでファイル構成も綺麗に階層にできる。でも、変数の宣言と使い道が直感的じゃない。チーム開発に障害与えそうな気がする
HelperとPartialの併用
ViewはViewで、RubyはRubyコードで管理して欲しいな
実現すると、単体的に分解できるようになりどれを置き換えてもそこまで問題になれない
Component化だな...
# helper.rb
module Test
def forms
@params.each do |param|
form param
end
end
def form param
render partial: 'view/test', locals: {
param: param
message: param.message
}
end
end
// View.slim
.html
.body
= forms
// view/_test.slim
.form
= message
ControllerがViewを呼び出したときに、実はView::Helperも一緒に呼び出している。 なので、インスタンス変数も参照可能な状態になっている
検証
Viewは、必要なパラメータを表示するだけでいいし
Helperは、parseの役目を果たしている
もし、フレームワークが変わったとしてもファイルじたいは違う形で変数を受け取ればよくなるし、変数の処理もrbファイルの中で済ませるもで、リファクタリングがしやすくなる。
Controllerで、パラメータの処理を一箇所でやる必要もなくなる。Modelでやればいいじゃんと思ってる人も多いと思うが、現実は厳しいなのだ
ただし、全部言い訳ではない。ファイルが増えることと、対応関係の問題が多く発生する。ちゃんとしたドキュメントがないとかなり厳しい
結果
個人的には、3番が一番すぎなのだが、チーム開発になるとかなり諸刃の剣になる。
ModelからViewまで、全部一人でやりますと言った場合は進めします、ドキュメントもファイルこと書けばすぐ書けそうだし
2番は無難に使いやすいかな、1番はないな
まあー、まだ探検中なので、まだいいのあれば書きます☺️