【Ruby】メソッドについて

# 記事概要
Rubyのメソッドについて、まとめる。

# まとめ(ターミナルで実行するメソッド)
## putsメソッド
ターミナルに値を出力するメソッド

```ruby
# 値を出力する
puts 値

irb(main):001> puts 1
1
=> nil
irb(main):002> puts "Taro"
Taro
=> nil
```

##  getsメソッド
ターミナルに値の入力機能を起動するメソッド

```ruby_gets.rb
# 入力機能を起動する
gets

puts '名前を入力してください'
name = gets  # 入力が完了するまで、コードの読み込みは停止
puts "名前は#{name}です。"  # 入力が完了するまで、この行は読み込まれない。
```

ターミナルでの実行結果('太郎'と入力)
```
% ruby ruby_gets.rb
名前を入力してください
太郎
名前は太郎
です。
```

[サンプルコード](https://github.com/likapantrip/ruby)の`ruby_gets.rb`を参照

# まとめ(文字列が持つメソッド)
## lengthメソッド
文字列の文字数を数えるメソッド

```ruby
# 文字列の文字数数える
文字列.length

# 文字列「Hello World」の文字数を数える
irb(main):001:0> "Hello World".length
=> 11
```

## to_iメソッド
文字列を数値に変換するメソッド

```ruby
# 文字列を数値に変換する
文字列.to_i

# 文字列「30」を数値「30」に変換
irb(main):001:0> "30".to_i
=> 30

# 文字列が数字以外の場合、0に変換
irb(main):002> 'a'.to_i
=> 0

# to_iで文字列を数値に変換し、計算
irb(main):003:0> "100".to_i + 400
=> 500
```

## chompメソッド
文字列の末尾に存在する改行を取り除いた文字列を返すメソッド

```ruby_chomp.rb
# 文字列の末尾に存在する改行を取り除く
文字列.chomp

puts '名前を入力してください'
name = gets.chomp
puts "名前は#{name}です。"  # #{name}の後に改行されず、1行で結果が表示される
```

ターミナルでの実行結果('太郎'と入力)
```
% ruby ruby_chomp.rb
名前を入力してください
太郎
名前は太郎です。
```

[サンプルコード](https://github.com/likapantrip/ruby)の`ruby_chomp.rb`を参照

# まとめ(数値が持つメソッド)
## to_sメソッド
数値を文字列に変換するメソッド

```ruby
# 数値を文字列に変換する
数値.to_s

# 数値「20」を文字列「20」に変換
irb(main):001:0> 20.to_s
=> "20"

# to_sで数値を文字列に変換し、文字列と連結
irb(main):001:0> "i am " + 20.to_s + " years old."
=> i am 20 years old.
```

# まとめ(配列が持つメソッド)
## lengthメソッド
配列の要素を数えるメソッド

```ruby
# 配列の要素数を数える
配列.length

# 配列内の要素数を数える
irb(main):001:0> ['あお', 'きいろ', 'あか'].length
=> 3
```

# まとめ(ハッシュが持つメソッド)
## mergeメソッド
ハッシュを結合させるメソッド
2つのハッシュを、1つにまとめられる

```ruby
# ハッシュtweetを作成
irb(main):001> tweet = { text: "桜が咲いてた！", image: "sakura.jpeg" }
=> {:text=>"桜が咲いてた！", :image=>"sakura.jpeg"}

# ハッシュuidを作成
irb(main):002> uid = { user_id: "1" }
=> {:user_id=>"1"}

# 2つのハッシュを結合
irb(main):003> tweet.merge(uid)
=> {:text=>"桜が咲いてた！", :image=>"sakura.jpeg", :user_id=>"1"}
```

# まとめ(繰り返し処理)
## timesメソッド
指定した数値の回数だけ繰り返し処理を行えるメソッド

```ruby
# 数値の回数だけ繰り返す
数値.times do
  # 繰り返す処理
end

irb(main):001> i = 0
=> 0
irb(main):002* 3.times do
irb(main):003*   puts i += 1
irb(main):004> end
1
2
3
=> 3
```

## eachメソッド
配列やハッシュの要素1つ1つに対して、要素の数だけ繰り返し処理が行えるメソッド

```ruby
# 配列やハッシュの数だけ、繰り返す
[配列 or ハッシュ].each do | [変数] |
  # 繰り返す処理
end
```

###  ハッシュを使用
繰り返し処理で、キーと値を表示できる

```ruby
# ハッシュの生成
irb(main):001> members = {Naruto: 147.5, Sasuke:153, Sakura:150.1}
=> {:Naruto=>147.5, :Sasuke=>153, :Sakura=>150.1}

# 繰り返し処理
irb(main):002* members.each do |key,value|
irb(main):003*   puts "#{key}は、#{value}cm"
irb(main):004> end
Narutoは、147.5cm
Sasukeは、153cm
Sakuraは、150.1cm
=> {:Naruto=>147.5, :Sasuke=>153, :Sakura=>150.1}
```

###  配列を使用
繰り返し処理で、要素を表示できる

```ruby
# 配列の生成
irb(main):001> members = ['Naruto', 'Sasuke', 'Sakura']
=> ["Naruto", "Sasuke", "Sakura"]

# 繰り返し処理
irb(main):002* members.each do |name|
irb(main):003*   puts name
irb(main):004> end
Naruto
Sasuke
Sakura
=> ["Naruto", "Sasuke", "Sakura"]
```

# まとめ(クラスが持つメソッド)
## newメソッド
定義済のクラスをもとに、インスタンスを新規生成するメソッド

### イメージ
[![Image from Gyazo](https://i.gyazo.com/f1a2690357ecdb877006c822aff99498.png)](https://gyazo.com/f1a2690357ecdb877006c822aff99498)

```ruby
# インスタンスを生成する
クラス名.new

# Carクラスを定義
irb(main):001* class Car
irb(main):002> end
=> nil

# Carクラスのインスタンスを生成し、変数pink_carに代入
irb(main):003> pink_car = Car.new
=> #<Car:0x000000010861c8b8>

# 変数pink_carを出力
irb(main):004> pink_car
=> #<Car:0x000000010861c8b8>
```

## createメソッド
インスタンスを新規生成し、引数の情報でデータを保存するメソッド

```ruby
# インスタンスを新規生成し、引数の情報でデータを保存する
モデル.create(カラム名: 値)

# Postモデルのインスタンスを新規生成
# 引数(content: "今日はお花見")の情報でデータを保存する
irb(main):001> Post.create(content: "今日はお花見")
  TRANSACTION (2.5ms)  BEGIN
  Post Create (21.1ms)  INSERT INTO `posts` (`content`, `created_at`, `updated_at`) VALUES ('今日はお花見', '2025-04-19 18:19:01.939093', '2025-04-19 18:19:01.939093')
  TRANSACTION (3.8ms)  COMMIT
=> 
#<Post:0x00000001104a8150
 id: 1,
 content: "今日はお花見",
 created_at: Sat, 19 Apr 2025 18:19:01.939093000 UTC +00:00,
 updated_at: Sat, 19 Apr 2025 18:19:01.939093000 UTC +00:00>
```

## updateメソッド
既存データを更新するメソッド

```ruby
# Postモデル(postsテーブル)に新規データを作成し、変数postに代入
irb(main):001> post = Post.create(content: 'hello!')
  TRANSACTION (0.2ms)  BEGIN
  Post Create (1.1ms)  INSERT INTO `posts` (`content`, `created_at`, `updated_at`) VALUES ('hello!', '2025-04-25 19:19:36.718169', '2025-04-25 19:19:36.718169')
  TRANSACTION (2.6ms)  COMMIT
=> 
#<Post:0x000000010d26b3b8
...

# contentカラムの内容を更新する
irb(main):002> post.update(content: 'こんにちは！')
  TRANSACTION (0.3ms)  BEGIN
  Post Update (0.6ms)  UPDATE `posts` SET `posts`.`content` = 'こんにちは！', `posts`.`updated_at` = '2025-04-25 19:19:49.803033' WHERE `posts`.`id` = 3
  TRANSACTION (1.1ms)  COMMIT
=> true
```

## destroyメソッド
テーブルに格納されたレコードを削除するメソッド

```ruby
# 削除対象を変数に格納
irb(main):001> item = Item.find(1)
  Item Load (2.8ms)  SELECT `items`.* FROM `items` WHERE `items`.`id` = 1 LIMIT 1
=> #<Item:0x0000000108c00680 id: 1, name: "白ズボン", price: 1000, created_at: Fri, 25 Apr 2025 15:00:50.313053000 UTC +00:00, updated_at: Fri, 25 Apr 2025 15:00:50.313053000 UTC +00:00>

# 変数に格納したレコードを削除
irb(main):002> item.destroy
  TRANSACTION (1.4ms)  BEGIN
  Item Destroy (17.3ms)  DELETE FROM `items` WHERE `items`.`id` = 1
  TRANSACTION (8.4ms)  COMMIT
=> #<Item:0x0000000108c00680 id: 1, name: "白ズボン", price: 1000, created_at: Fri, 25 Apr 2025 15:00:50.313053000 UTC +00:00, updated_at: Fri, 25 Apr 2025 15:00:50.313053000 UTC +00:00>
```

## findメソッド
メソッドの引数にレコードのidを記述すると、idに対応するレコードを取得するメソッド

```ruby
# モデルに格納されているid=引数のレコードを取得する
モデル名.find(レコードのid)

# Post(postsテーブル)に格納されているid=1のデータを取得
# 変数postに代入
irb(main):001> post = Post.find(1)
  Post Load (0.4ms)  SELECT `posts`.* FROM `posts` WHERE `posts`.`id` = 1 LIMIT 1
=> 
#<Post:0x000000010f272080
...

# 変数postに格納されているcontentカラムの情報を出力する
irb(main):002> post.content
=> "今日はお花見"
```

## allメソッド
モデルに格納されている全てのレコードを取得するメソッド

```ruby
# モデルに格納されている全てのレコードを取得する
モデル名.all

# Post(postsテーブル)に格納されている全レコードを取得
# 変数postsに代入
irb(main):001> posts = Post.all
  Post Load (0.3ms)  SELECT `posts`.* FROM `posts` /* loading for pp */ LIMIT 11
=> 
[#<Post:0x000000010988e230
...

# 変数postsに格納されているレコードを順番に表示
irb(main):002* posts.each do |p|
irb(main):003*   puts p.content
irb(main):004> end
  Post Load (0.5ms)  SELECT `posts`.* FROM `posts`
今日はお花見
入学式🌸
たのしみ〜
=> 
[#<Post:0x000000010b9d5790
  id: 1,
  content: "今日はお花見",
  created_at: Fri, 11 Apr 2025 16:24:14.857418000 UTC +00:00,
  updated_at: Fri, 11 Apr 2025 16:24:14.857418000 UTC +00:00>,
 #<Post:0x000000010b9d5650
  id: 2,
  content: "入学式🌸",
  created_at: Fri, 11 Apr 2025 16:24:21.815603000 UTC +00:00,
  updated_at: Fri, 11 Apr 2025 16:24:21.815603000 UTC +00:00>,
 #<Post:0x000000010b9d5510
  id: 3,
  content: "たのしみ〜",
  created_at: Fri, 11 Apr 2025 16:24:28.480224000 UTC +00:00,
  updated_at: Fri, 11 Apr 2025 16:24:28.480224000 UTC +00:00>]
```

## whereメソッド
引数部分に条件を指定することで、テーブル内の「条件に一致したレコードのインスタンス」を配列の形で取得できるメソッド

```ruby
モデル.where('検索対象となるカラムを含む条件式')
```

```ruby
# idが4未満のtweetsテーブルのインスタンスを配列で取得
1] pry(main)> Tweet.where('id < 4')
  Tweet Load (3.4ms)  SELECT `tweets`.* FROM `tweets` WHERE (id < 4)
=> [#<Tweet:0x0000000103fa9d68
  id: 1,
  text: "桜が咲いてた！",
  image: "sakura.jpeg",
  created_at: Wed, 30 Apr 2025 16:37:16.661315000 UTC +00:00,
  updated_at: Wed, 30 Apr 2025 16:38:37.716922000 UTC +00:00,
  user_id: 1>,
 #<Tweet:0x0000000105b89f60
  id: 2,
  text: "春だなあ",
  image: "haru.jpeg",
  created_at: Wed, 30 Apr 2025 16:37:49.328601000 UTC +00:00,
  updated_at: Wed, 30 Apr 2025 16:37:49.328601000 UTC +00:00,
  user_id: 2>,
 #<Tweet:0x0000000105b89ec0
  id: 3,
  text: "葉桜になってる",
  image: "hazakura.jpeg",
  created_at: Wed, 30 Apr 2025 16:38:13.788717000 UTC +00:00,
  updated_at: Wed, 30 Apr 2025 16:38:13.788717000 UTC +00:00,
  user_id: 1>]

# idが4未満かつuser_idが1のtweetsテーブルのインスタンスを配列で取得
[2] pry(main)> Tweet.where('id < 4').where(user_id: 2)
  Tweet Load (0.6ms)  SELECT `tweets`.* FROM `tweets` WHERE (id < 4) AND `tweets`.`user_id` = 2
=> [#<Tweet:0x0000000105a642e8
  id: 2,
  text: "春だなあ",
  image: "haru.jpeg",
  created_at: Wed, 30 Apr 2025 16:37:49.328601000 UTC +00:00,
  updated_at: Wed, 30 Apr 2025 16:37:49.328601000 UTC +00:00,
  user_id: 2>]
```

### LIKE句
whereメソッドと一緒に使い、あいまいな文字列の検索をするときに使用する

#### 曖昧文字列
|文字列|意味|
|-|-|
|%|任意の文字列（空白文字列含む）|
|_|任意の1文字|

#### 実行サンプル
|実行例|詳細|
|-|-|
|where('title LIKE(?)', "a%")|aから始まるタイトル|
|where('title LIKE(?)', "%b")|bで終わるタイトル|
|where('title LIKE(?)', "%c%")|cが含まれるタイトル|
|where('title LIKE(?)', "d_")|dで始まる2文字のタイトル|
|where('title LIKE(?)', "_e")|eで終わる2文字のタイトル|

## Date
日付を取得するオブジェクト

https://docs.ruby-lang.org/ja/2.6.0/class/Date.html

# まとめ(インスタンスが持つメソッド)
## initializeメソッド
インスタンスが生成された時に、自動的に実行される処理を定義するメソッド

```ruby
# インスタンス生成時に自動的に実行される
def initialize
  # 処理
end

# Carクラスを定義
irb(main):001* class Car
irb(main):002*   def initialize
irb(main):003*     puts "Carクラスのインスタンスが生成されました"
irb(main):004*   end
irb(main):005*   def ride_car(weight)
irb(main):006*     @car_weight = weight
irb(main):007*   end
irb(main):008> end
=> :ride_car

# Carクラスのインスタンスを生成し、変数pink_carに代入
# initializeメソッドは自動的に処理が実行される
irb(main):009> pink_car = Car.new
Carクラスのインスタンスが生成されました
=> #<Car:0x0000000108fa9a20>

# インスタンスメソッドは、呼び出しが必要
irb(main):010> pink_car.ride_car(900)
=> 900
```

## saveメソッド
レコードを保存するメソッド

```ruby
# テーブルにレコードを保存する
モデルのインスタンス.save

# モデルのインスタンスを生成し、変数postに代入
irb(main):001> post = Post.new
=> #<Post:0x0000000105d39ce8 id: nil, memo: nil, created_at: nil, updated_at: nil>

# インスタンスにデータを追加
irb(main):002> post.memo = 'こんにちは！'
=> "こんにちは！"

# テーブルにレコードを保存
irb(main):003> post.save
  TRANSACTION (3.4ms)  BEGIN
  Post Create (7.6ms)  INSERT INTO `posts` (`memo`, `created_at`, `updated_at`) VALUES ('こんにちは！', '2025-04-08 09:53:47.491589', '2025-04-08 09:53:47.491589')
  TRANSACTION (3.2ms)  COMMIT
=> true
```

# まとめ(Gemが持つメソッド)
## devise_parameter_sanitizerメソッド
[devise](https://qiita.com/likapantrip/items/f89df3e5076ef3c78ae8)導入時に使用できるメソッド

deviseのUserモデルに関わる「ログイン」「新規登録」などのリクエストからパラメーターを取得でき、`params`のようなメソッド

`permit`メソッドと組み合わせることにより、deviseに定義されているストロングパラメーターに対して、自分で新しく追加したカラムも指定して含められる

メソッド名は、`configure_permitted_parameters`を使用することが多い

```ruby
private
def configure_permitted_parameters
  # deviseのUserモデルに追加のパラメーターを許可
  devise_parameter_sanitizer.permit(:deviseの処理名, keys: [:許可するキー])
end
```

- `permit`メソッドの第一引数
    |処理名|役割|
    |---|---|
    |:sign_in|サインイン（ログイン）の処理を行うとき|
    |:sign_up|サインアップ（新規登録）の処理を行うとき|
    |:account_update|アカウント情報更新の処理を行うとき|
- `permit`メソッドの第二引数
    配列でキー(各フォーム部品のname属性値)を指定する
    指定された名前と同じキーを持つパラメーターの取得を許可する

## user_signed_in?メソッド
[devise](https://qiita.com/likapantrip/items/f89df3e5076ef3c78ae8)導入時に使用できるメソッド

ログインしているかを判定するメソッド

```ruby
# ログインしているユーザーのとき
user_signed_in?
#=> true

# ログインしていないユーザーのとき
user_signed_in?
#=> false
```

## current_userメソッド
[devise](https://qiita.com/likapantrip/items/f89df3e5076ef3c78ae8)導入時に使用できるメソッド

現在ログインしているユーザーの情報を取得できるメソッド

```ruby
current_user.id
#=> 現在ログインしているユーザーのID
```

# まとめ(フレームワークが使用するメソッド)
## requireメソッド
Sinatraのような仕組み自体を読み込む際に使用するメソッド

```ruby
# PCにインストールしたSinatraをファイルに読み込む
require 'sinatra'
```