経緯
現在、とあるプログラミングスクールに通っているのですが、検索機能(検索窓)を実装する際に、処理をモデルとコントローラーを使い分けるように言われました。
えー… 全部コントローラーでいいじゃん…(もちろん、今では積極的に分けて使用していますよ!)
・コントローラー…DBからデータを取得したり、保存したり単純な処理のみ記載
・モデル…DBから取得した値に複雑な処理を行うものを記載
というイメージで使い分けています。
ただ、何故モデルで設定した『処理のカタマリ』をコントローラーで使えるのか理解できなかったので使いたくなかった、、いや使えなかったんですよね。
(この記事は検索機能の解説をするための記事ではありません。あくまでモデルの使い方について私の頭の整理です。)
検索機能の実装
class Tweet < ApplicationRecord
validates :text, presence: true
belongs_to :user
has_many :comments
def self.search(search)
return Tweet.all unless search
Tweet.where('text LIKE(?)', "%#{search}%")
end
end
※2〜4行目は必要のない記載ですが、あえて「モデルに書いてるよ」ってわかるように残してます。
また、見やすいように謎の改行が入っておりますがご容赦ください。
class TweetsController < ApplicationController
def search
@tweets = Tweet.search(params[:keyword])
end
end
理解不明ポイント
①コントローラーの「search」メソッドって何?
(リファレンスに載ってないぞ??)
リファレンスになんぞ載っていいる訳ないのです。
なぜなら「モデルで自作したメソッド」だから!!
②モデルの「self」ってなに?
(ググると、当たり前のように「クラスメソッド」って言われますが…)
- ここで詳しい説明はしませんが、こいつにはクラス名が代入されます。 (代入という表現はわかりやすくするために使用しています)
- tweet.rb(tweetモデル)の一行目を見てください。クラス名、なんだかわかりましたよね?
- つまり、「self.search(search)」は「「Tweet.search(search)」なんです。(どっかで見たような、)
③何故モデルで設定した『処理のカタマリ』をコントローラーで使えるの?
(いよいよ本題です)
なんとなく分かってきましたかね??
- コントローラーで使用している「Tweet.search(params[:keyword])」はモデルで自作したメソッド「self.search(search)」と同じなんです。
メソッドの正体
我々がよく使っている「findメソッド」や「includeメソッド」等の様々なメソッドって実は、
今回「searchメソッド」を自作したようにRailsのActiveRecordが作ってくれているんです!!
各モデルがActiveRecordを継承しているから、コントローラーでメソッドを使えているんですね!
(厳密には class Tweet < ApplicationRecord < ActiveRecord::Base)
tweet.rb(tweetモデル)の一行目を見れば記載がありますね。
アイツ
さて、長くなってきましたが一つ解決してないヤツがいますよね。
そう、結局「self = クラスメソッド」って何だったのか。
クラスメソッドは読んで字の如く、「クラス」に対して使用できるメソッドです。
「クラス」って何だったか思い出せますか??
わからない方はtweet.rb(tweetモデル)の一行目を見てみてください。
私もこれ以上はまだ理解できてません!!笑
謝辞
ちょっとわかりにくい説明だったかもしれませんが、プログラミング歴2ヶ月なので許してください。
(自分の頭は割と整理できました。)
ここまで長々と書かせていただきましが、最後まで読んでいただきありがとうございます。
もし、解釈が間違っている場合は、教えていただけるととても嬉しいです。
どんどはれ。