Rails6 のちょい足しな新機能を試す80（reselect編）

# はじめに

Rails 6 に追加された新機能を試す第80段。 今回は、 `reselect` 編です。
Rails 6 では、 モデルに `reselect` , ` reselect!` メソッドが追加されました。
`rewhere` や `reorder` があるので、 `reselect` もあった方が便利じゃないかということで追加されたみたいです。

Ruby 2.6.4, Rails 6.0.0 で確認しました。Rails 6.0.0.rc2 は `gem install rails` でインストールできます。

```shell
$ rails --version
Rails 6.0.0
```

今回は、 User モデルを作成して `rails console` を使って確認します。

# プロジェクトを作る

```shell
rails new rails_sandbox
cd rails_sandbox
```

# User モデルを作る

name と email の2つの属性をもつ User モデルを作ります。

```shell
bin/rails g model User name email
```

# seed データを作成する

seed データを作成します。

```ruby:db/seeds.rb
User.create(
  [
    { name: 'Taro', email: 'taro@example.com' },
    { name: 'Jiro', email: 'jiro@example.com' },
    { name: 'Hanako', email: 'hanako@example.com' }
  ]
)
```

# マイグレーションを実行し seed データを登録する

```shell
bin/rails db:create db:migrate db:seed
```

# rails console で確認する

`rails console` で確認します。

`User.select(:name, :email)` を `s1` に代入します。

```irb
irb(main):001:0> s1 = User.select(:name, :email)
  User Load (0.2ms)  SELECT "users"."name", "users"."email" FROM "users" LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<User id: nil, name: "Taro", email: "taro@example.com">, #<User id: nil, name: "Jiro", email: "jiro@example.com">, #<User id: nil, name: "Hanako", email: "hanako@example.com">]>

irb(main):002:0> s1
  User Load (0.8ms)  SELECT "users"."name", "users"."email" FROM "users" LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<User id: nil, name: "Taro", email: "taro@example.com">, #<User id: nil, name: "Jiro", email: "jiro@example.com">, #<User id: nil, name: "Hanako", email: "hanako@example.com">]>
```

s2 に `s1.reselect(:name)` を代入します。

```irb
irb(main):003:0> s2 = s1.reselect(:name)
  User Load (0.5ms)  SELECT "users"."name" FROM "users" LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<User id: nil, name: "Taro">, #<User id: nil, name: "Jiro">, #<User id: nil, name: "Hanako">]>
```

s2 で発行されるSQL は、 `name` カラムのみ取得しますが、s1 は `name` と `email` の2つのカラムを取得します。

```irb
irb(main):004:0> s2
  User Load (0.6ms)  SELECT "users"."name" FROM "users" LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<User id: nil, name: "Taro">, #<User id: nil, name: "Jiro">, #<User id: nil, name: "Hanako">]>

irb(main):005:0> s1
  User Load (0.7ms)  SELECT "users"."name", "users"."email" FROM "users" LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<User id: nil, name: "Taro", email: "taro@example.com">, #<User id: nil, name: "Jiro", email: "jiro@example.com">, #<User id: nil, name: "Hanako", email: "hanako@example.com">]>
```

s1 自体を変更したい場合は、 `reselect!` を使います。

```irb
irb(main):006:0> s1.reselect!(:name)
  User Load (0.6ms)  SELECT "users"."name" FROM "users" LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<User id: nil, name: "Taro">, #<User id: nil, name: "Jiro">, #<User id: nil, name: "Hanako">]>
irb(main):007:0> s1
  User Load (0.6ms)  SELECT "users"."name" FROM "users" LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<User id: nil, name: "Taro">, #<User id: nil, name: "Jiro">, #<User id: nil, name: "Hanako">]>
```

# 試したソース

試したソースは以下にあります。
https://github.com/suketa/rails_sandbox/tree/try080_reselect


# 参考情報

* [What is new in Rails 6.0](https://bogdanvlviv.com/posts/ruby/rails/what-is-new-in-rails-6_0.html)
* [Add reselect method](https://github.com/rails/rails/pull/33611)