Ruby on Railsでの良い書き方について

皆さん、こんにちは。新卒のズオンです。
この記事は[Linkbal(リンクバル)Advent Calendar 2019](https://qiita.com/advent-calendar/2019/linkbal)の14日目の記事です。
今回はRuby on Railsでの良い書き方を紹介します。 おそらく多くの人が既にこれらの書き方について知っていますが、私にとっては非常に便利だと思うので皆と共有したいです。 皆様からの提案をお待ちしております。 始めましょう。:smile:


##Hash

####dig
私たちはほとんどしばしばこのように書きます：

```ruby
if users[:id] && users[:id][:age] && users[:id][:age][:address]
  ...
end
```
`Hash＃Dig`を使用すると、`nil`参照を心配することなくて簡単に動的にアクセスできます。 この書き方が短くて、結果は変わりません。

```ruby
if user.dig :id, :age, :address
  ...
end
```
##Object

#### &.

例えばユーザーの住所があるかどうかを確認するとします。次のように書くことがよくあります。

```ruby

if user && user.address
  ...
end
```
`&.`を使用して上記のコードを書き換えることができます。

```ruby

if user&.address
  ...
end
```

####presence_in
もしブール条件の結果が実際に必要ない場合は、条件をメソッドに置き換えることができます。

```ruby
colors = [:red, :green, :blue]
color = colors.include?(params[:color]) ? params[:color] : :pink
```
または

```ruby

color = (colors.include?(params[:color]) && params[:color]) || :pink
```
下の書き方はもっと良くなります。

```ruby

params[:color].presence_in(colors) || :pink
```

####presence

もしオブジェクトに `""`または `[]`があるかどうかをチェックしたい場合は
このような代わりに：

```ruby
prefecture = params[:prefecture] if params[:prefecture].present?
area = params[:area] if params[:area].present?
region = prefecture || area || 'JP'
```

このように使ってください。

```ruby
params[:prefecture].presence || params[:area].presence || 'JP'
```

##Array

####zip

例えば同じ数の要素を持つ2つの配列があり、この配列の要素をキーに変換し、他の配列の要素を対応する値に変換したい場合、次のようにします。

```ruby
arr_1 = ["1", "2", "3"]
arr_2 = ["a", "b", "c"]

Hash[arr_1.zip arr_2] # => {"1" => "a", "2" => "b", "3" => "c"}
```
####any?とall?
少なくとも1つの要素が条件を満たす場合に` true`を返したい時に`any?`を使ってください。

```ruby
arr = [2, 3, 4]
arr.any? { |n| n > 3 }
# => true
arr.any? { |n| n > 4 }
# => false
```

すべての要素が条件を満たす場合に`true`を返したい場合は、`all?`を使用してください。

```ruby
arr = [2, 3, 4]
arr.all? { |n| n > 1 }
# => true
```
####any?(&:blank?)とall?(&:blank?)
配列は`nil`とか`""`の要素があるかどうか確認したいときに

```ruby
arr = Array.new([1, 2, nil, ""])
arr.any?(&:blank?) # => true 
```
以外に配列は全ての要素が`nil`とか`""`あるかどうかチェックしたい場合に

```ruby
["", nil].all?(&:blank?) # => true
[1, 2, "", nil].all?(&:blank?) # => false
```

####selectとreject 
条件を満たす要素を返す。

```ruby
[1, 2, 3, 4].select{ |n| n > 2 }

# => [3, 4]
```
条件を満たさない要素のみを選択するには、`select`の代わりに`reject`を使用できます。

```ruby
[1, 2, 3, 4].reject{ |n| n > 2 }

# => [1, 2]
```


####count

条件を満たす要素の数を返します。

```ruby
arr = [1, 2, 3, 4, 4, 7, 7, 7, 9]
arr.count { |i| i > 5 }
# => 4
```

####compact
配列内の`nil`要素を削除します。

```ruby
numbers_and_nil = [1, 2, 3, nil, nil, 6]
only_numbers = numbers_and_nil.reject(&:nil?) # => [1, 2, 3, 6]
```
上記の書き方代わりに下記のようにもっと良くなります。

```ruby
numbers_and_nil = [1, 2, 3, nil, nil, 6]
only_numbers = numbers_and_nil.compact         # => [1, 2, 3, 6]
```

####sample

ランダム要素を返します。

```ruby
users[rand(users.size)]
# 同じに
users.sample
```
##String

```ruby

# snake_caseをcamel_caseに変換します
"my_book".camelize # => "MyBook"

# snake_caseになります
"MyBook".underscore # => "my_book"

# kebab_caseになります
"my_book".dasherize # => "my-book"

# 複数形になります
"book".pluralize            # => "books"
"account".pluralize         # => "accounts"
"ruby".pluralize            # => "rubies"
"tooth".pluralize           # => "teeth"

# 単数になります
"books".singularize            # => "book"
"customers".singularize        # => "customer"
"wolves".singularize           # => "wolf"

# クラス名に変換します（camel_case + 単数形）
"my_book".classify  # => "MyBook"
"my_books".classify # => "MyBook"

# テーブル名に変換します（snake_case + 複数形）
"my_book".tableize # => "my_books"
"MyBook".tableize  # => "my_books"

# 不要なスペースを削除します
"    My    \r\n  \t   \n   book      ".squish # => "My book"
```

`String`の短縮メソッドについて詳しく知りたい場合は、https://apidock.com/rails/String を参考してください。

#おわりに
上記で私が知っている`Hash`や`Object`や`Array`や`String`メソッドのいくつか良い書き方を紹介しました。 もちろんもっと良い書き方がたくさんあるので皆様からの提案をお待ちしております。読んでくれてありがとうございます。 またね。:raised_hand:

#参考
https://apidock.com/rails/String
https://api.rubyonrails.org/