箱のプログラミング日記。

渋谷の自社開発企業でRails書いてます。

モデルに書くゲッターの使いどころ

まだRubyRailsの学習を初めて3週間程度の初学者ですが、

今日「初学者ならではの目線」である疑問が浮かびました。

 

def review_average
 reviews.average(:rate).round
end

 

何かの値を返してくれるだけのために定義するメソッドをゲッターと呼びますが、

今までいまいち使い方が分かりませんでした。

 

 

 

今までの学習では、例えば

「viewでデータベースの値を使いたい時は

コントローラーのアクション内でインスタンス変数にでもしておけば簡単」

と思っていました。

 

controller

def create
 @tweet = Tweet.create
end

 

 

だって、createアクションが呼ばれた後にcreateビューが表示されるんだから。

ビューの中で使いたい値は、アクション内でDBから持って来とけば良いじゃないの〜

 

このほうが、初学者の私には簡単で見やすいと思っていたのですが

実際の現場では違うそうで。

 

 

本来コントローラーというのは、

指定のリクエストがあった際に動かすアクションを定義しておくためのもので、

 

アクション内に変数を定義したりとかは、

あまりつらつら書かないことが多いのだそう。

 

 

もちろん上の例のように、

「ビューの至る所で使われるであろう汎用的な値」であれば

アクション内で定義するのも良いそうなのですが、

 

ビューで使われるのが1箇所だけで、かつ

DBから取り出した後に何らかの処理を加えた上で定義したい、汎用性の低い値

モデルの中とかで定義しておくのが良いそうです。

 

 

コントローラーのアクション内で定義するのがふさわしい変数
def show
 @tweet = Tweet.find(params[:id])
end

あるidのtweetレコードを配列で取り出している。

 

この状態から、viewファイルで

<%= @tweet.nickname %>   ・・・ツイートした人のニックネーム

<%= @tweet.comments %> ・・・そのツイートに対するコメント

<% @tweet.user.id %> ・・・ツイーとした人のユーザーid

 

というように、定義された@tweetを元に色々な値を取り出せるので汎用性が高い。

 

 

コントローラーのアクション内で定義するのがふさわしくない変数

 

def show
 @average = Food.reviews.average(:rate).round
end

レビューの評価の平均値を定義したものです。

 

上の例のように、「配列型になっていて汎用性がある」とは言いづらい。

ビューファイルで記述されるのもどこか一箇所だけになりそうです。

テーブル名でないものをインスタンス変数として定義するのも、確かに少し不思議な感じがします。

 

 

このような値はアクション内にインスタンス変数として定義するのではなく、

返り値を返してくれるメソッドを定義するのが得策のようです。

def review_average
reviews.average(:rate).round
end

 

データベースとのやりとりなので、モデルにかくのが良いかと。

 

 

まだまだ初学者の私ですが、

「なぜそうなるのか」「実際の現場ではどうなのか」

「どうすれば見やすく美しいコードが書けるのか」ということを意識して、

今後も学習を進めていきたいな、と思った体験でした。