どうもこんにちは。
今回はRailsでモデルファイルで定義したメソッドにself
をつける時とつけない時の違いについて説明します。(おまけでバリデーションメソッドについても説明しています。)
モデルにメソッドを定義する理由
1. 全体で利用可能
モデルに定義したメソッドはアプリケーション全体で利用可能となるメソッドです。そのため、コントローラやビュー、他のモデルの中でも使用することができます。
2. 処理の共通化
アプリケーション内で何度も同じ処理をする必要がある場合があります。その時に同じ処理の共通化を目的としてモデルにメソッドに定義し、同じ処理をしたい箇所でメソッドを呼び出すことでコードが簡略化できます。
3. バリデーションを定義
本来は、validates
メソッドを使用してカラムに対して「空白禁止」や「文字数制限」を定義します。大体のバリデーションは1行で完結できます。しかし、二つのカラムにデータが入っていない場合のバリデーションを定義するときには、俗にいう「バリデーションメソッド」を定義します。
selfを付けない場合
self
を付けないメソッドはインスタンスメソッドというものです。
まず、Userテーブルに以下のデータが登録されているとします。
カラム名 | 型 | 値 |
---|---|---|
id | integer | 1 |
first_name | string | 試験 |
last_name | string | 太郎 |
以下のようなメソッドを定義していたとします。
class User < ApplicationRecord
def full_name
"#{first_name} #{last_name}"
end
end
メソッドを使用する時には、インスタンスに対して使用します。
# インスタンス生成
user = User.find(1)
# インスタンスに対してメソッドを呼び出す
puts user.full_name
バリデーションメソッドはインスタンスに対してバリデーションをかけるのでself
をつけずにメソッドを定義します。
selfをつける場合
self
を付けるメソッドはクラスメソッドというものです。
クラスメソッドは、データの登録を行う場合や複雑な条件を指定してデータを取得する場合に使用します。
class User < ApplicationRecord
def self.user_create
User.create(first_name: "試験", last_name: "次郎")
end
end
メソッドを使用する時には、クラスに対して使用します。
# モデルに対してメソッドを呼び出す
User.user_create
バリデーションとして定義する場合
単純なバリデーションであれば、以下のようにしてバリデーションを設定することができます。
# 空白禁止
validates :name, presence: true
# 最大文字数制限
validates :note, length: { maximum: 1000 }
しかし、「名前かあだ名のどちらか一方は入力されるようにする」というバリデーションを定義するとします。
まずは、以下のようにバリデーションを定義します。
validate :name_or_nickname
これでname_or_nickname
というメソッドを使用してバリデーションを定義できるようになります。
次にメソッドを定義します。
def name_or_nickname
# どちらかが入力されていればOK
return if name.present? || nickname.present?
errors.add(:name, :blank) if name.blank?
errors.add(:nickname, :blank) if nickname.blank?
end
以上のようにメソッドを定義することで複雑なバリデーションを設定することができます。
まとめ
最初の方はコントローラにメソッドを定義するだけで乗り切れますが、複雑なアプリケーションになるにつれて、コントローラだけではうまくコードを書けなくなってきます。
そのため、モデルにメソッドを定義して使用できるようになると非常に便利です。
以上