LoginSignup
22
4

More than 1 year has passed since last update.

【初学者向け】Rails(ActiveRecord)でselfの理解を深める - インスタンスメソッド クラスメソッド -

Last updated at Posted at 2022-09-08

はじめに

本記事は、著者自身のクラスに対する理解を深めるために
例を用いてクラスについて解説していく記事となります!

対象の読者像

・Railsでselfの使い方がイマイチ掴めていない方
・Rails触ったことあるけどselfの理解が曖昧な方

基本事項

example.rb
class Example
  attr_accessor :person
  
  def initialize(person)
    @person = person
  end
  
  def self.ikemen
    self.person
  end

  def busamen
    self.person
  end

end

さて、問題です!

問1

クラスメソッドはどれのことを指すでしょうか?

答え
def self.ikemen
  self.person
end

問2

問1のクラスメソッドはどのように呼び出すでしょうか?

答え
ターミナル
Example.ikemen

問3

問2のクラスメソッドを呼び出すとどのような結果が返ってきますか?
また、なぜその結果になるのか説明して下さい。

答え

==>(戻り値)undefined method `person' for Example:Class (NoMethodError)
==>(理由)selfは、Exampleクラス自身であるため(personというクラス変数が存在しないためエラーになる)

問4

インスタンスメソッドはどれのことを指すでしょうか?

答え
def busamen
  self.person
end

問5

問4のインスタンスメソッドはどのように呼び出すでしょうか?

答え
ターミナル
busaiku = Example.new("motoya")
busaiku.busamen

問6

問5のインスタンスメソッドを呼び出すとどのような結果が返ってきますか?
また、なぜその結果になるのか説明して下さい。

答え

==>(戻り値)motoya
==>(理由)selfは、Example.new("motoya")で生成したインスタンス自身であるため

Rails(ActiveRecord)でのself

前提として、下記の状態とします。

schema.rb
ActiveRecord::Schema.define(version: 2022_08_23_103957) do

  create_table "tsubuyakis", force: :cascade do |t|
    t.string "title"
    t.string "content"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

end
tsubuyaki.rb
class Tsubuyaki < ApplicationRecord
  before_create :check_ikemen?

  def self.ikemen?
    where(title:"ikemen")
  end

  scope :ootuka, -> { where(title:"ikemen") }

  def check_ikemen?
    unless self.title == "ikemen"
      throw :abort
    end
  end

end

問7

上記のクラスメソッドはどれ?

答え
答え
def self.ikemen?
  where(title:"ikemen")
end

scope :ootuka, -> { where(title:"ikemen") }

①実はscopeはクラスメソッドと同義
②where等、検索機能で使われる場合が多い

参考:https://qiita.com/Ryuta1346/items/87be4100d7322a26acff

問8

上記のインスタンスメソッドはどれ?

答え
答え
def check_ikemen?
  unless self.title == "ikemen"
    throw :abort
  end
end

トランザクション処理で使われる

問9

下記のようにターミナル上でcreateした場合どのようにインスタンスメソッドが振る舞われるか説明して下さい。

ターミナル
rails c
Tsubuyaki.create(title: "busamen", content: "busaiku")
Tsubuyaki.create(title: "ikemen", content: "motoya")
答え

Tsubuyaki.create(title: "busamen", content: "busaiku")
create前にcheck_ikemen?が作動して、
createしようとしたtitleが"ikemen"ではないので
トランザクション内の処理が失敗しロールバックされる。
(DB上に保存されない)

Tsubuyaki.create(title: "ikemen", content: "motoya")
createしようとしたtitleが"ikemen"なので正常にDB上に保存される

問10

下記のようにターミナル上でikemen?した場合どのようにクラスメソッドが振る舞われるか説明して下さい。

ターミナル
rails c
Tsubuyaki.ikemen?
答え
ターミナル
Tsubuyakiクラス (=tsubuyakisテーブル)に対して、
where(title:"ikemen")の条件に一致するデータを配列形式で取得する
今回は、データ1つしかないので下記が出力される

[#<Tsubuyaki:0x0000000122074158
  id: 1,
  title: "ikemen",
  content: "motoya",
  created_at: Thu, 08 Sep 2022 10:10:25.752938000 UTC +00:00,
  updated_at: Thu, 08 Sep 2022 10:10:25.752938000 UTC +00:00>]

終わりに

初学だとRailsとRubyは別個に考えがちですが
今回のようにRailsではselfはどうやって使ってるんだろう?
というテーマで考えると一段とRailsと仲良くなれた気がしました!
初学の方は是非お試しください!

22
4
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
4