はじめに
コントローラーに書いたアクションの処理をモデルにメソッド化する際、メソッドについての理解が浅かったため呼び出し方、書き方に悩まされた。そのため、今回は実例を元に使い方について、記事にまとめてみた。
※これまで個人的にはモデルやクラス、インスタンスなど似たようなイメージを持っていたが、RailsのモデルはRubyのクラス。インスタンスはテーブルのレコードと考えれば理解しやすくなった。
実例(クラスメソッド)
修正前の状態
def search_result
@topics = Topic.where('title LIKE ?', "%#{params[:title]}%")
end
図1はTopicモデルのテーブルから、あいまい検索した結果をインスタンス変数である、@topics
に格納している。これをメソッド化し、モデルに定義する。
修正後のコード
def search_result
@topics = Topic.search(params[:title])
end
def self.search(title)
where('title LIKE ?', "%#{title}%")
end
検索するためのメソッドなので、メソッド名はモデルにsearch
としてメソッド化、その際の注意点として大きく2点ある。
1,使用するメソッドがクラスメソッドであるということ。
search
メソッドはクラスに使用するため、クラスメソッドでないといけない。そのため図3のようにメソッド名の前にself
を付ける。このself
はクラス自身を表している。ちなみにself
が抜けているとインスタンスメソッドとなり、クラスから生成されたインスタンスにしか使用できない。
2,受け取ったparams
を引数としてメソッドに渡さないといけないこと。
ビューからフォームで受け取ったparams
をメソッドの引数として渡してあげないと、中身の処理が機能しないため、受け取った値は引数で渡してあげること。
実例(インスタンスメソッド)
修正前の状態
def destroy
# 省略
if @current_user.admin_status == true
redirect_to(admin_path)
else
redirect_to("/")
end
end
図4はトピックの削除機能で@current_user
ログインしているユーザーが管理者であるかないかで条件分岐をしている。このadmin_status == true
をメソッド化し、モデルに定義する。
修正後のコード
def destroy
# 省略
if @current_user.admin?
redirect_to(admin_path)
else
redirect_to("/")
end
end
def admin?
admin_status == true
end
管理者であるかを確認するためのメソッドなので、メソッド名はモデルにadmin?
としてメソッド化。また、その際の注意点として大きく2点ある。
1,使用するメソッドがインスタンスメソッドであるということ。
admin?
メソッドはインスタンスに使用するため、インスタンスメソッドでないといけない。そのため図6のようにそのままメソッドを書くことでインスタンスメソッドになる。
2,trueやfalseを返す時のメソッドは末尾に?
を付けること。
Rubyでは慣用的に、真偽値を返すタイプのメソッドを示すために使われる。そのため、末尾に?
を付けることで直感的にもわかりやすくなる。
学び
今回、痛感したのは何気なく使っているメソッド周りのことを全然理解できていなかったということ。何をしてもエラーの連続で訳がわからない状態になったりもしたが、サポートしていただいておかげで、定義しているメソッドがクラスメソッドなのか、インスタンスメソッドなのか?またそのメソッドをどう呼ぶのか?をより意識するようになれた。これからも努力を惜しまず理解を深めていきたい。