今まで知らなかった開発で使ったRailsメソッド備忘録

## なぜ記事を書こうと思ったか
  Railsアプリの開発をする際に適切なメソッドを調べる時がある為、今まで知らなかったまたは理解が曖昧な開発で使用するメソッドを中心にこの記事にまとめようと思います。

## railsメソッド一覧
### Regexpクラス
- escapeメソッド
メタ文字をエスケープした結果を返す。

```
pattern = Regexp.escape('1+2=3,2*3=6')
p pattern
# '1//+2=3,2//*3=6'
```

### Stringクラス
- subメソッド
文字列中で pattern にマッチした最初の部分を文字列 replace で置き換えた文字列を生成して返す。

```
greeting = "I am name. My favorite food is meet."
pattern = { "name" => "James", "meet" => "beef" }
replaced = article.sub(/name|meet/, pattern)

p replaced # "I am James. My favorite food is beef."
```

### Arrayクラス
- flattenメソッド
自身を再帰的に平坦化した配列を生成して返す。flatten! は自身を再帰的かつ破壊的に平坦化し、平坦化した場合は平坦化した自身をしてない場合は nil を返します。

```
array1 = [1, 2, [3, 4], 5]
array2 = [1, 2, 3]
p array1.flatten # [1, 2, 3, 4, 5]
p array1.flatten! # [1, 2, 3, 4, 5]
p array2.flatten! # nil
```

### Hashクラス
- flattenメソッド
設定する引数に従って自身を平坦化した配列を生成して返します。

```
hash =  {"name"=> "tanaka", "hobbies" => ["サッカー", "映画鑑賞"], "age" => 20}
a.flatten     #=> ["name", "tanaka", hobbies, ["サッカー", "映画鑑賞"], "age", 20]
a.flatten(1)  #=> ["name", "tanaka", hobbies, ["サッカー", "映画鑑賞"], "age", 20]
a.flatten(2)  #=> ["name", "tanaka", hobbies, "サッカー", "映画鑑賞", "age", 20]
a.flatten(0)  #=> [["name", "tanaka"], [hobbies, ["サッカー", "映画鑑賞"]], ["age", 20]]
a.flatten(-1) #=> ["name", "tanaka", hobbies, "サッカー", "映画鑑賞", "age", 20]
```

- has_key?
ハッシュにキーが存在するか確認する。

```
hash = {"name"=> "tanaka", "hobbies" => ["サッカー", "映画鑑賞"], "age" => 20}
hash.has_key?("name") # true
hash.has_key?("height") # false
```

- has_value?
ハッシュに値が存在するか確認する。

```
hash = {"name"=> "tanaka", "hobbies" => ["サッカー", "映画鑑賞"], "age" => 20}
hash.has_value?(20) # true
hash.has_value?(25) # false
```

### JSONクラス
- parseメソッド
JSON形式の文字列をRubyのHashオブジェクトに変換して返す

```
json = "{"Name":"太郎","age":23}"
hash = JSON.parse(json)
p hash # {"Name"=>"太郎", "age"=>23}
```

- generateメソッド
与えられたオブジェクトを一行の JSON 形式の文字列に変換して返す

```
json = "{"Name":"太郎","age":23}"
hash = JSON.generate(json)
p hash # {\"Name\":\"太郎\", \"age\":23}
```

### TIMEクラス
- zoneメソッド
タイムゾーンを表す文字列を返す。

```
Time.zone = 'Tokyo'
Time.zone # #<ActiveSupport::TimeZone:0x00007f86108d1a38 @name="Asia/Tokyo", @tzinfo=#<TZInfo::DataTimezone: Asia/Tokyo>, @utc_offset=nil>
```

- strftimeメソッド
時刻をフォーマット文字列に従って文字列に変換した結果を返す。

```
now = Time.zone.now
p now.strftime('%Y/%m/%d') # 2022/09/02
```

- beginning_of_monthメソッド
月の初めの日付を取得

```
time = Time.now
p time.beginning_of_month # Sat, 01 Aug 2022
```

- end_of_monthメソッド
月の最後の日付を取得

```
time = Time.now
p time.end_of_month # Sat, 31 Aug 2022
```

### CGIクラス
- escapeメソッド
与えられた文字列を URL エンコードした文字列を新しく作成し返す。

```
p CGI.escape('株式会社IT')   #=> "%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BEIT"
```

- unescapeメソッド
与えられた文字列を URL デコードした文字列を新しく作成し返します。

```
p CGI.unescape('%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BEIT')   #=> "株式会社IT"
```

### Exceptionクラス
- backtraceメソッド
例外処理を行うときに、例外が発生したときのプログラムの呼び出し状況を取得する。どの部分で例外が発生したか確認できる。

```
begin
  raise 'dummy'
rescue => e
  puts e.backtrace.join("\n")
  # ["file_name.rb:2:in `method_name'", "filename.rb:2"]
end
```

### Sanitizationクラス
- sanitiza_sql_like
SQL LIKEステートメント内で安全に使用できるように、 string をサニタイズし、「_」、および「％」のすべての出現をエスケープする。

```
User.where('name LIKE ?', "%#{ActiveRecord::Base.sanitize_sql_like("田中")}%")
# User Load (4.4ms)  SELECT `users`.* FROM `users` WHERE (name LIKE '%田中%')
```

### EnvironmentInquirerクラス
- envメソッド
現在の環境を確認んすることができる

```
Rails.env
# "development"
```

### loggerライブラリ
- loggerメソッド
Rubyからログを出力するメソッド

```
logger.debug('*debug logger')
logger.info('*info logger')
logger.warn('*warn logger')
logger.error('*error logger')
logger.fatal('*fatal logger')
logger.unknown('*unknown logger')

# 以下ログ出力
D, [2017-09-22T10:08:39.414406 #16980] DEBUG -- : *debug logger
I, [2017-09-22T10:08:39.414406 #16980]  INFO -- : *info logger
W, [2017-09-22T10:08:39.414406 #16980]  WARN -- : *warn logger
E, [2017-09-22T10:08:39.414406 #16980] ERROR -- : *error logger
F, [2017-09-22T10:08:39.414406 #16980] FATAL -- : *fatal logger
A, [2017-09-22T10:08:39.414406 #16980]   ANY -- : *unknown logger
```

### URIライブラリ
- encode_www_form_componentメソッド
文字列を URL-encoded form data の1コンポーネントとしてエンコードした文字列を返します。

```
p URI.encode_www_form_component('エンコードしたい')
# "%E3%82%A8%E3%83%B3%E3%82%B3%E3%83%BC%E3%83%89%E3%81%97%E3%81%9F%E3%81%84"
```

### ActiveRecord
- includesメソッド
関連するテーブルをまとめて取得

```
Employee.includes(:department)
# SELECT "employees".* FROM "employees"
# SELECT "departments".* FROM "departments" WHERE "departments"."id" IN (1)
```

- mergeメソッド
複数の条件を併合する

```
question = "田中"
User.where(age: 20)
    .merge(
      User.where('name LIKE ?',
                          "%#{ActiveRecord::Base.sanitize_sql_like(question)}%")
      .or(User.where('email LIKE ?',
                              "%#{ActiveRecord::Base.sanitize_sql_like(question)}%"))
    )
# User Load (1.4ms)  SELECT users.* FROM `users` WHERE `age` = 20 AND (name LIKE '%田中%' OR email LIKE '%田中%')
```

- maximumメソッド
カラムの最大値を返す

```
User.maximum('age')
# SELECT MAX("users"."age") AS max_id FROM "users"
```

- enumメソッド
1つのカラムに対して複数個の定数を持たせる為のメソッド

```
enum sex: { men: 0, women: 1}
p User.sex
# { "men" => 0, "women" => 1}
```

### ActiveModel
- as_jsonメソッド
モデルをハッシュ形式のJSONに変換

```
user.as_json
# {id: 1, name: "Tanaka Taro", age: 24, created_at: "2022-08-31T17:27:133.000Z"}
```

- groupメソッド
指定したカラムごとにデータをまとめることができる。

```
User.group(:company_id).count
SELECT COUNT(*) AS count_all, `users`.`company_id` AS users_company_id FROM `users` GROUP BY `users`.`company_id`
# {1=> 22, 2=> 40}
```

- eager_loadメソッド
左外部結合を使ってすべてのレコードを取得する

```
User.eager_load(:company)
# SELECT "users"."id" AS t0_r0, "users"."name" AS t0_r1, ...
# FROM "users" LEFT OUTER JOIN "companies" ON "companies"."user_id" =
# "users"."id"
```

### ActiveJob
- perform_nowメソッド
同期的にSampleJobを呼び出す

```
def execute_now
  puts '実行開始'
  SampleJob.perform_now('実行中')
  puts '実行終了'
end

# 実行開始
# Performing SampleJob (Job ID: e6859c49-4ec4-41d2-820f-eef63615cc51) from Async(default) with arguments: "実行中"
# [JOB] start: 実行中
# [JOB] end: 実行中
# Performed SampleJob (Job ID: e6859c49-4ec4-41d2-820f-eef63615cc51) from Async(default) in 3005.48ms
# 実行終了
```

- perform_laterメソッド
非同期的にSampleJobを呼び出す

```
def execute_later
  puts '実行開始'
  SampleJob.perform_later('実行中')
  puts '実行終了'
end

# 実行開始
# Enqueued SampleJob (Job ID: e6859c49-4ec4-41d2-820f-eef63615cc51) to Async(default) with arguments: "実行中"
# Performing SampleJob (Job ID: e6859c49-4ec4-41d2-820f-eef63615cc51) from Async(default) with arguments: "実行中"
# 実行終了
# [JOB] start: 実行中
# [JOB] end: 実行中
# Performed SampleJob (Job ID: e6859c49-4ec4-41d2-820f-eef63615cc51) from Async(default) in 3005.48ms
```

## 最後に
改めて今回まとめた事でどういうものが出力できるか理解できました。どこか間違っている所があれば指摘して頂けると嬉しいです。
ここまで読んで下さりありがとうございました〜

## 参考資料
- [RubyでもJSONを扱える！parseメソッドの基本と応用例を紹介](https://style.potepan.com/articles/28558.html)
- [module function JSON.#generate](https://docs.ruby-lang.org/ja/latest/method/JSON/m/generate.html)
- [instance method Time#zone](https://docs.ruby-lang.org/ja/latest/method/Time/i/zone.html)
- [instance method Exception#backtrace](https://docs.ruby-lang.org/ja/latest/method/Exception/i/backtrace.html)
- [singleton method CGI.escape](https://docs.ruby-lang.org/ja/latest/method/CGI/s/escape.html)
- [Railsドキュメント/日付関連](https://railsdoc.com/page/date_related)
- [Ruby 3.1 リファレンスマニュアル/escape](https://docs.ruby-lang.org/ja/latest/method/CGI/s/escape.html)
- [module ActiveRecord::Sanitization::ClassMethods](https://runebook.dev/ja/docs/rails/activerecord/sanitization/classmethods)
- [Railsドキュメント/includes](https://railsdoc.com/page/includes)
- [Railsドキュメント/as_json](https://railsdoc.com/page/as_json)
- [Railsでモデルを4段階joinする方法で、もう一度理解するjoinsとmerge](https://qiita.com/TeruhisaFukumoto/items/007ad22cc170d297dbcc)
- [instance method Array#flatten](https://docs.ruby-lang.org/ja/latest/method/Array/i/flatten.html)
- [instance method Hash#flatten](https://docs.ruby-lang.org/ja/latest/method/Hash/i/flatten.html)
- [Railsドキュメント/カラムの最大値](https://railsdoc.com/page/maximum)
- [instance method Time#strftime](https://docs.ruby-lang.org/ja/latest/method/Time/i/strftime.html)
- [（備忘録）【Rails】groupメソッドについて](https://note.com/standenglish/n/n9cbd9679618d)
- [Railsドキュメント/eager_load](https://railsdoc.com/page/eager_load)
- [ActiveJobのperform_laterとperform_nowの違い](https://qiita.com/jnchito/items/3482a30262874b80a8e4)
- [Railsでlogを出力しdebugする](https://qiita.com/Kashiwara/items/f8a4030da6b17e96fabf)
- [【Ruby入門】loggerの使い方まとめ](https://www.sejuku.net/blog/19387)
- [【Rails】 envメソッドで環境を確認する方法と各コマンドの指定方法](https://pikawaka.com/rails/env)
- [Rails.env.production?の正体](https://takagi.blog/what-rails-env-production/)
- [【Rails】 enumチュートリアル](https://pikawaka.com/rails/enum)
- [クラス・モジュールの継承リスト: URI](https://docs.ruby-lang.org/ja/latest/class/URI.html)
- [【Ruby】文字列置換メソッドsub()とgsub()を使いこなそう](https://hataworakuni.net/substitute-in-ruby)
- [正規表現関連の便利メソッド](https://qiita.com/jnchito/items/3c4197c23460cafd12db)