as_jsonとto_jsonの違いをまとめてみる

## はじめに
ActiveRecordのオブジェクトをJSON形式に直すときはto_jsonを使ってJSON形式に直していると思います。
それとは別に、as_jsonといったものもあります。
初めて見たときは、似てるけど何が違うんだろうと思っていました。
今回は、頭の中を整理しながら、違いをまとめてみようと思います。

## as_jsonとは
オブジェクトをハッシュや配列など、JSONエンコードが可能なオブジェクトに変換してくれます。特定の属性を含めたり除外したりできます。
とりあえず、どのような出力となるか試してみます。

### 1レコードをas_jsonした場合
1レコードの場合はハッシュ形式で表示されます。
```rb
@users = User.find(1)

## puts @users.as_json
{"id"=>1, "name"=>"山田 太郎", "email"=>"sample1@sample.com", "created_at"=>"2024-07-20T13:46:10.150Z", "updated_at"=>"2024-07-20T13:46:10.150Z"}
## puts @users.as_json.class
Hash
```

### 全レコードをas_jsonした場合
全レコードの場合は、配列形式で表示されます。
```rb
@users = User.all

## puts @users.as_json
{"id"=>1, "name"=>"山田 太郎", "email"=>"sample1@sample.com", "created_at"=>"2024-07-20T13:46:10.150Z", "updated_at"=>"2024-07-20T13:46:10.150Z"}
{"id"=>2, "name"=>"山田 太郎", "email"=>"sample2@sample.com", "created_at"=>"2024-07-20T13:46:10.186Z", "updated_at"=>"2024-07-20T13:46:10.186Z"}
{"id"=>3, "name"=>"山田 太郎", "email"=>"sample3@sample.com", "created_at"=>"2024-07-20T13:46:10.198Z", "updated_at"=>"2024-07-20T13:46:10.198Z"}
{"id"=>4, "name"=>"山田 太郎", "email"=>"sample4@sample.com", "created_at"=>"2024-07-20T13:46:10.212Z", "updated_at"=>"2024-07-20T13:46:10.212Z"}
{"id"=>5, "name"=>"山田 太郎", "email"=>"sample5@sample.com", "created_at"=>"2024-07-20T13:46:10.222Z", "updated_at"=>"2024-07-20T13:46:10.222Z"}
{"id"=>6, "name"=>"山田 太郎", "email"=>"sample6@sample.com", "created_at"=>"2024-07-20T13:46:10.237Z", "updated_at"=>"2024-07-20T13:46:10.237Z"}
{"id"=>7, "name"=>"山田 太郎", "email"=>"sample7@sample.com", "created_at"=>"2024-07-20T13:46:10.251Z", "updated_at"=>"2024-07-20T13:46:10.251Z"}
{"id"=>8, "name"=>"山田 太郎", "email"=>"sample8@sample.com", "created_at"=>"2024-07-20T13:46:10.263Z", "updated_at"=>"2024-07-20T13:46:10.263Z"}
{"id"=>9, "name"=>"山田 太郎", "email"=>"sample9@sample.com", "created_at"=>"2024-07-20T13:46:10.279Z", "updated_at"=>"2024-07-20T13:46:10.279Z"}
{"id"=>10, "name"=>"山田 太郎", "email"=>"sample10@sample.com", "created_at"=>"2024-07-20T13:46:10.290Z", "updated_at"=>"2024-07-20T13:46:10.290Z"}
## puts @users.as_json.class
Array
```

### 値の取得
カラムを指定して、値の取得を行うこともできます。
```rb
## 1レコードの場合
## puts @users.as_json['name']
山田 太郎

## 全レコードの場合
## puts @users.as_json.map { |user| user['name'] }
山田 太郎
山田 太郎
山田 太郎
山田 太郎
山田 太郎
山田 太郎
山田 太郎
山田 太郎
山田 太郎
山田 太郎
```

## to_jsonとは
オブジェクトをJSON文字列に変換します。文字列なので、特定の属性を含めたり除外したりはできません。
こちらもためしてみます。

全レコードを表示してみます。string形式で一行につながって出力されます。
as_jsonのようにカラムを指定して、出力しようとするとエラーになります。
```rb
@users = User.all

## puts @users.to_json
 [{"id":1,"name":"山田 太郎","email":"sample1@sample.com","created_at":"2024-07-20T13:46:10.150Z","updated_at":"2024-07-20T13:46:10.150Z"},{"id":2,"name":"山田 太郎","email":"sample2@sample.com","created_at":"2024-07-20T13:46:10.186Z","updated_at":"2024-07-20T13:46:10.186Z"},{"id":3,"name":"山田 太郎","email":"sample3@sample.com","created_at":"2024-07-20T13:46:10.198Z","updated_at":"2024-07-20T13:46:10.198Z"},{"id":4,"name":"山田 太郎","email":"sample4@sample.com","created_at":"2024-07-20T13:46:10.212Z","updated_at":"2024-07-20T13:46:10.212Z"},{"id":5,"name":"山田 太郎","email":"sample5@sample.com","created_at":"2024-07-20T13:46:10.222Z","updated_at":"2024-07-20T13:46:10.222Z"},{"id":6,"name":"山田 太郎","email":"sample6@sample.com","created_at":"2024-07-20T13:46:10.237Z","updated_at":"2024-07-20T13:46:10.237Z"},{"id":7,"name":"山田 太郎","email":"sample7@sample.com","created_at":"2024-07-20T13:46:10.251Z","updated_at":"2024-07-20T13:46:10.251Z"},{"id":8,"name":"山田 太郎","email":"sample8@sample.com","created_at":"2024-07-20T13:46:10.263Z","updated_at":"2024-07-20T13:46:10.263Z"},{"id":9,"name":"山田 太郎","email":"sample9@sample.com","created_at":"2024-07-20T13:46:10.279Z","updated_at":"2024-07-20T13:46:10.279Z"},{"id":10,"name":"山田 太郎","email":"sample10@sample.com","created_at":"2024-07-20T13:46:10.290Z","updated_at":"2024-07-20T13:46:10.290Z"}]
## puts @users.to_json.class
String
```

## まとめ
**as_json**
- オブジェクトをハッシュや配列など、JSONエンコードが可能なオブジェクトに変換
- 特定の属性を含めたり除外したりできる

**to_json**
- オブジェクトをJSON文字列に変換
- 特定の属性を含めたり除外したりはできない

to_jsonはJSONの形式なので、view側にインスタンス変数で渡して、jsを使用し表示することができます。
as_jsonはそのまま渡すとJSON形式ではないので、jsでJSONとして受け取ることはできません。
デバックで表示するときは、as_jsonは改行してくれるので見やすいですね。