ぺろのなるほどブログ

ぺろがなるほどした話を書きます

【scopeの使い方】scopeを使って記述を短くしてみたら、コードは短くなったけどめっちゃ時間がかかった話

こんにちわ、ぺろです。
毎日暑いですね。
私は逆に室内の冷房にやられてすっかり冷房疲れです。


今日は、scopeの使い方で詰まった時の話をしようと思います。
なんで突然scopeの話?て感じですが、今日復習ノート読み直していたら、
めっちゃなるほどしたので、誰かのためになったら嬉しいと思ったので書いておきます。
なるほどしたら⭐️をください☺️

"scope"とは??

→ scopeを使ってモデルに定義してメソッド化することによって、コントローラの記述を短くできる。

今回のゴール

→ 1人のuserの評価を取得し、good、normal、badをそれぞれ表示する。

キーワード

  1. lengthの存在
  2. whereの返り値は配列
  3. 引数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で表示。

コントローラの記述がめっちゃスッキリしました!
この記述に到るまでめっちゃ時間かかりました。


なるほどな〜〜〜〜〜!!


ぺろ