【scopeの使い方】scopeを使って記述を短くしてみたら、コードは短くなったけどめっちゃ時間がかかった話
こんにちわ、ぺろです。
毎日暑いですね。
私は逆に室内の冷房にやられてすっかり冷房疲れです。
今日は、scopeの使い方で詰まった時の話をしようと思います。
なんで突然scopeの話?て感じですが、今日復習ノート読み直していたら、
めっちゃなるほどしたので、誰かのためになったら嬉しいと思ったので書いておきます。
なるほどしたら⭐️をください☺️
"scope"とは??
→ scopeを使ってモデルに定義してメソッド化することによって、コントローラの記述を短くできる。
今回のゴール
→ 1人のuserの評価を取得し、good、normal、badをそれぞれ表示する。
キーワード
- lengthの存在
- whereの返り値は配列
- 引数2つの与え方と取得の仕方。
登場人物
- Evaluationモデル
- itemコントローラ
- view/items/show/haml
Before
(itemコントローラ) @good = Item.where(user_id: Evaluation.find(1).evaluation) @normal = Item.where(user_id: Evaluation.find(2).evaluation) @bad = Item.where(user_id: Evaluation.find(3).evaluation)
After
(Evaluationモデル) scope :evaluation, -> (count, user) { where(evaluation: count, user_id: user) }
(itemコントローラ) @good = Evaluation.evaluation(1, @user) @normal = Evaluation.evaluation(2, @user) @bad = Evaluation.evaluation(3, @user)
(view/items/show.haml) #{@good.length} #{@normal.length} #{@bad.length}
詰まったところ
→ 定義するモデルと指定のコントローラが同じ名前出ないといけないと思い込んでいました。
解説していきます。
上記の通り、記述するモデルとコントローラは同じでないといけないと思っていたので、
ずっとItemモデルとitems controllerにscopeの記載をしていたので、全く動いてくれませんでした。
よくよく考えてみるとわかることなんですが、評価の値取り出すのはItemモデルじゃなくね??
ということでEvaluationモデルに記述を引っ越しさせたところ、値がコントローラに飛んできた!!!!
Evaluationモデルでは、count(評価の数)とuser(1人のuser)の2つを引数にしてevaluationに代入しています。
itemコントローラのevaluationは、scopeで作ったメソッドevaluationです。それに対して同じuser_idの評価1だけを引数の配列にして@goodで取得。
view/items/show.hamlで、@goodの中の配列の数をlengthで表示。
コントローラの記述がめっちゃスッキリしました!
この記述に到るまでめっちゃ時間かかりました。
なるほどな〜〜〜〜〜!!
ぺろ