LoginSignup
0
0

More than 1 year has passed since last update.

Railsコールバック、ActiveRecord::Enum

Posted at

コールバックによる制御

コールバックとは
特定の処理に引っ掛けて別の処理を呼ぶことをコールバックと言います

メリット

  • 前処理、後処理などを宣言的に書くことができる
  • 必ず保存後に行いたい処理がある時に、実行の漏れを防ぐことができる

コールバックの基本的な使い方
(例)
本の名前を保存する前に、名前に"Dog"が含まれていた場合
"Dog Cute"と文字列を置き換える

class Book < ApplicationRecord
  略
  before_validation do
    self.name = self.name.gsub(/Dog) do |matched|
        "Dog Cute #{matched}"
    end
  end

  # メソッドを使って書くこともできます
  before_validation :add_Cute_to_dog(独自メソッド)

  def add_Cute_to_dog
    self.name = self.name.gsub(/Dog/) do |matched|
        "Dog Cute #{matched}"
    end
  end
            
end

上記の記述のgsubメソッドとは何?

gsubメソッド

gsubメソッドはマッチしたすべての部分を特定の文字列に置換します。
パターンには文字列や正規表現が使えます。

実行結果
irb(main):001:0> Book.create(
irb(main):002:1* name: "My Dog",
irb(main):003:1* publsiher: Publisher.find(1),
irb(main):004:1* price: 1000,
irb(main):005:1* )

[["name", "My Dog Cute Dog"], 
 ["price", 1000],
 ["created_at", "2022-07-28 10:00:58.584937"],
 ["updated_at", "2022-07-28 10:00:58.584937"], 
 ["publisher_id", 1]
]

ActiveRecord:Enum

ActiveRecordにenum型とは
モデルの数値のカラムに対してプログラム上で扱えるように名前を定義してくれるもの


本に販売の状況に関する状況を追加する場合
販売の状況はテーブルに定義する際に数ないバリエーションのため、文字列として保存するのが効率的になります
このような数値を扱うコードをプログラムで扱う場合
下記のようになります。

RESERVATION = 0 予約受付
NOW_ONSALE = 1 発売中
END_SALE = 発売終了

このような時に役に立つのがenum型になります
Bookモデルに販売状況のカラムを追加し、値を管理する方法としてenum型を定義します

rails g migration AddStatusToBooks sales_status:integer
rails db:migrate

次に、enumクラスメソッドにカラム名と対応する値を定義する。
定義する値はハッシュ形式で名称と値の組み合わせで定義。
または、名称を文字列かシンボルの配列とすることができる。

app/models/book.rb
class Book < ApplicationRecord

  enum sales_status: {
    reservation: 0, # 予約受付中
    now_on_sale: 1, # 発売中
    end_of_sales: 2, # 発売終了
  }

上記のようにし、データを保存してみると

irb(main):013:0> Book.create(
irb(main):014:1* name: "samplebook",
irb(main):015:1* publisher: Publisher.find(1),
irb(main):016:1* sales_status: 1,
irb(main):017:1* price: 1000,
irb(main):018:1* )
<Book id: 3, name: "samplebook", 
published_on: nil, 
price: 1000, 
created_at: "2022-07-30 09:37:44.399443000 +0000", 
updated_at: "2022-07-30 09:37:44.399443000 +0000", 
publisher_id: 1, 
sales_status: "now_on_sale"

先ほどのカラムの出力結果を見てみると、
保存の際に数値で行なったが定義した文字列で戻ってきている

このようにenum型を利用すると、コード上で分かりやすいシンボルなどで指定しつつ、
DB上の定義に合わせて保存することが可能となります。

Enumで定義された状態を見たい場合

ステータスごとに述語メソッドで状態を確認する子おtができる

irb(main):013:0> book.now_on_sale?
=> true
irb(main):015:0> book.end_of_sales?
=> false

DBに保存されている実際の値を確認したい場合
カラム名_before_type_castメソッドで確認することができます。

irb(main):016:0> book.sales_status_before_type_cast
=> 1

また、enumの定義を確認したい場合、
カラム名の複数形メソッドをクラスメソッドとして呼び出します

irb(main):019:0> Book.sales_statuses
=> {"reservation"=>0, "now_on_sale"=>1, "end_of_sales"=>2}
0
0
0

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
0
0