概要
下記記事を参考に作成したコントローラー内のロジックを
何度も記述しておりましたのでリファクタリングのため、
メソッド化してモデルに定義しました。
その際、インスタンスメゾッド?クラスメゾッド?なにそれ…!となりましたので
ざっくり理解した内容と合わせて記事にしました。
参考:【Rails】ユーザー1人の全ての投稿に紐づく「イイね」の合計数を表示する方法
参考:【Ruby】クラスメソッドとインスタンスメソッドについてザクッと分かりやすく説明してみる
参考:Railsのモデルに書いたメソッドってどうやってコントローラで使うの?
元の記述
一部カットしていますが、今回モデルに移す
『userが持つ全投稿のいいね合計を算出するロジック』はこのように記述しています。
※今回投稿はhoge、いいねはfavorite。いいね合計はインスタンス変数@favorites_countへ格納します。
def show
@user = User.find(params[:id])
# ユーザーが持つ全投稿のいいね合計
@hoges = @user.hoges
@favorites_count = 0
@hoges.each do |hoge|
@favorites_count += answer.favorites.count
end
end
インスタンスメソッド化してモデルに定義
先に結論から記載します。
def show
@user = User.find(params[:id])
# all_favoritesというメソッドを別途モデルに定義する
@favorites_count = @user.all_favorites
end
def all_favorites
favorites_count = 0
hoges.each do |hoge|
favorites_count += hoge.favorites.count
end
# favorites_countを返してほしいので最後に記述
favorites_count
end
記述内容理解
備忘録のため記載します。
間違い、補足があればご教示いただけますと幸いです。
モデルに記述するメソッドは大きく、クラスメソッドとインスタンスメソッドがあります。
- クラスメソッド:クラスオブジェクトから呼び出す。
- インスタンスメソッド:インスタンスオブジェクトから呼び出す。
今回は、userに紐づく形でメゾッドを呼び出すため、インスタンスメソッドです。
※User.find(params[:id])で取得した@userに紐づくイメージです。
インスタンスメソッド内では、インスタンスをselfとして記述することができます(省略可能)。
省略しましたが、下記のようにも記述できます。
(なお、元々コントローラーにあった@hoges = @user.hogesはhoges = hogesと同意になり、省略できます。
また、@が付いてないのはView等に渡す変数ではないからです。)
def all_favorites
favorites_count = 0
# コントローラー内の@userをここではselfと記述可能。
# self.hogesは@user.hogesの意味
self.hoges.each do |hoge|
favorites_count += hoge.favorites.count
end
favorites_count
end
コントローラーで@user.all_favoritesと記述しているので、@userの全投稿に紐づくいいね数ですが
例えば、rails cで、User.find(1).all_favoritesとやると、id1のuserの全投稿に紐づくいいね数が取得できます。
なお、1点補足で、インスタンスメソッドを使用する際は、
1つのデータから呼び出すことが必須になります。
つまり、user.all_favoritesはイケますが、users.all_favoritesは呼び出せず、エラーになりますのでご注意ください。
この辺りはインスタンスとは?のような話になるかと思いますが、まだよく分かりません・・