モデルにメソッドを記述することでコントローラに記述するコードを減らすことができます。スキニーコントローラ、ファットモデルを実現できるというわけですね。ここではモデルにメソッドを追加するための方法を解説します。まずは前提として以下の2つのメソッドがあることを覚えておいてください。
これらは用途によって使い分けられるメソッドになります。今言っても理解がむずかしいと思いますが、インスタンスメソッドは「オブジェクトに対するメソッド」、クラスメソッドは「オブジェクトになる前のメソッド」ということになります。
これから、それらを解説するので、今はわからなくても心配いりません。徐々に理解できるように解説していきたいと思います。ではarticle.rbを使って解説しますので、article.rb(articleモデル)を開いて下さい。
例えば「記事を1000円で売る」ということを想定してみましょう。その時に消費税を計算する必要があったとしますね。現在(2019年現在)は消費税が8%なので、それを上乗せした額を算出したいと思います。
そんな時はインスタンスメソッドを作ると便利です。モデルにprice_with_taxというメソッドを追加します。このメソッドを呼び出すことで1000円に1.08をかけて、消費税8%を上乗せして返してくれます。
article.rb
def price_with_tax
1000 * 1.08
end
では実際にRailsコンソールで試してみましょう。
# ターミナル
$ rails c #railsのコンソールに入る
このメソッドをターミナルで試してみます。1080.0と返されるはずです。
$ article = Article.new
$ article.price_with_tax
#=> 1080.0
メソッドは、引数を取る事も出来ます。
今の状態では1000円+消費税という決まったコード(ハードコード)になっています。本当は値段や今後上がるかもしれない消費税を自由に設定したいですよね。
articleモデルを以下のように変更しpriceとtaxを柔軟に処理できるようにします。
# article.rb
def price_with_tax(price, tax)
price * tax
end
今までからの変更は以下のようになります。
次にターミナルで結果を確認してみましょう。
コンソールを立ち上げて $article = Article.new とコードを入力します。
# ターミナル
$ article = Article.new
そしてメソッドを呼び出してみましょう。
$ article.price_with_tax(1000, 1.08)
すると以下のような処理を経て1080.0と返ってくるはずです。
引数で先ほどと同じ1000という数字を指定しているので、返される結果も同じ1080.0になっています。みなさんは1000だけではなく2000や3000という他の値段でも試してみてください。
インスタンスに入っているデータを取り出して使用する事が出来ます。例えば以下のようにオブジェクトを作成してarticle1という変数入れます。
Railsコンソール
article1 = Article.new
article1.title = "test1"
article1.body = "test body1"
article1.reverse_title #=> "1tset"
そしてarticle1に入っているデータを取り出して文字を反対表示にしています。
# article.rb
def reverse_title
title.reverse #titleに入っているインスタンスデータが使用される
end
ここで注目してももらいたいのは「reverse_title」というメソッドの中で使用している「title」という部分です。唐突に出てきますが、これはこのオブジェクトのtitle属性にアクセスしています。このtitleと書いただけで、このオブジェクトにセットされた値を取り出すことができます。今回で言うとtitleと書くだけでtest1という文字列が返ってきます。
上ではオブジェクトの持っているデータを使用できることがわかりました。今度はオブジェクトの持っているデータの更新方法を学びましょう。
まずオブジェクトのデータを更新する場合は、以下のように書きます。
self.属性名 = "更新したい値"
例えばtitle属性を「update data」という文字に変更する場合は以下のように書きます。
self.title = "update data"
オブジェクトのtitle属性に「反対文字」にするメソッドを作成してみます。
article.rb
def reverse_title
self.title = title.reverse
end
Railsコンソールで実行してみると反対文字が返ってくることがわかります。
ターミナル
article1 = Article.new
article1.title = "test1"
article1.body = "test body1"
article1.reverse_title #=> "1tset"
では、実際の使い方を以下例で見ていきましょう。これは、読了時間を表示する為のオリジナルメソッドです。ちょっとザックリですが、1分間に100文字読めるという前提でのメソッドになります。
# article.rb
def reading_time_predicition
# 文字数を取得する
text_count = body.size
# 文字数を100(1分)で割って、この記事を読むのに何分かかるかをreading_time変数に入れる
reading_time = text_count / 100
# 0が返ってきたら1分以内、それ以上だったら〜分を返す
reading_time == 0 ? "1分以内" : "約#{reading_time}分"
end
このメソッドを使って、読了時間を表示するようビューに追加します。
# articles/show.html.erb
<strong>読了予想時間:
<%= @article.reading_time_predicition %>分
</strong>
<strong>Body:</strong>
<%= @article.body %>
英語のタイトルをすべて大文字にするupcase_titleというインスタンスメソッドを自作してみましょう。そのメソッドを呼ぶとtitle が TITLEになるようにします。大文字にするにはRubyのupcaseメソッドを使用してください。
無料ビデオ講座のお知らせ
Skillhub [スキルハブ]では無料の動画講座を多数公開しています。他校だと数万円するような講座が無料で受講できます。