どうもチャンクノです。
今個人アプリで勝率を表示するページを作っています。
メソッド作成に困リ果てた結果、attr_accessorを使って解決したお話です。
今回は少し長くなります。
初学者の方が見ると参考になる部分があるかもしれません。
まずは下記のコードを見てみましょう。
viewの記述
<%= @trade.win_rate(current_user) %>
model側の記述
def win_rate(current_user)
trades = Trade.where("trades.user_id" => current_user.id)
win_trades = trades.where("trades.result" => "勝").count
(win_trades / trades.count.to_f * 100).floor
end
これで一応勝率が導き出せます。
が!!!
はっきり言ってこれは全然よくないコードです。
なぜだかわかりますか?
なぜかというと、月ごとの勝率を出すなど他のパターンが出てきた場合。
メソッド名だけ変えて記述します。
def month_win_rate(current_user)
trades = Trade.where("trades.user_id" => current_user.id)
win_trades = trades.where("trades.result" => "資産増").count
(win_trades / trades.count.to_f * 100).floor
end
こういう感じでメソッドを作るたびに必ず引数にcurrent_userを取る必要が出てきます。
また、同じ処理を何回も書いてしまう羽目にもなります。
これは保守性に優れていなく、非常によろしくないです。
全体の勝率を表示するだけなら10000歩譲っていいかもしれません。
が、自分は月ごとの勝率などを出すことも考えているのでこのままではダメでした。
そこで何を使ったかというとタイトルにある通りattr_accessorです。
attr_accessorの内容まで書いてしまうと非常に長くなるのでご自身で調べてみてください🙇♂️
参考までに
https://qiita.com/Hassan/items/0e034a1d42b2335936e6
attr_accessorを使った結果先ほどのコードがどのように変化するかというと、、、
controlller
def index
@trade = Trade.new(current_user_id: current_user.id)
end
view
<%= @trade.win_rate %>
model
attr_accessor :current_user_id
def win_rate
(search_win_trades_count / search_user_trades.count.to_f * 100)
end
def search_user_trades
Trade.where("trades.user_id" => current_user_id)
end
def search_win_trades_count
search_user_trades.where("trades.result" => "勝").count
end
メソッドを作るたびにcurrent_userを引数に取る必要がなくなり、とてもスッキリしましたね。
また、メソッドの処理も別のメソッドに切り分けることで、変更点があっても容易になりました。
同じクラス内にあるメソッドは他のメソッド内でも使うことができるので覚えておくといいと思います。
ちなみに初学者の方がこの内容を理解できたら天才だと思います。
そんなものがあるんだな程度で頭の片隅に置いとけば大丈夫です。
では長くなりましたが今日はこの辺で!
皆様よきプログラミングライフを🙏
偉そうに書いてしまいましたが、これがクソコードである場合は遠慮なくお教えください。