Rails で Active Record のデータを キーが id, 値が Active Record であるような Hash を作る方法を備忘録として残しておく
環境
- ruby: 3.0.4
- rails: 6.1.0
実際のコード
index_by, inject, pluck + to_h メソッドのいずれかを使用する
前提
データの登録状態
id | book_id | name |
---|---|---|
1 | 1 | 少年誌 |
2 | 1 | 青年誌 |
3 | 1 | ビジネス |
4 | 1 | 自己啓発 |
[Rails Console]
categories = Category.all.index_by(&:id)
#=> {
#=> 1=>
#=> #<Category:0x0000562b92c5fcb0
#=> id: 1,
#=> book_id: 1,
#=> name: "少年誌",
#=> created_at: Wed, 24 Aug 2022 02:54:05.711796000 UTC +00:00,
#=> updated_at: Wed, 24 Aug 2022 02:54:05.711796000 UTC +00:00>,
#=> 2=>
#=> #<Category:0x0000562b92c97160
#=> id: 2,
#=> book_id: 1,
#=> name: "青年誌",
#=> created_at: Wed, 24 Aug 2022 02:54:45.283884000 UTC +00:00,
#=> updated_at: Wed, 24 Aug 2022 02:54:45.283884000 UTC +00:00>,
#=> 3=>
#=> #<Category:0x0000562b92c97098
#=> id: 3,
#=> book_id: 2,
#=> name: "ビジネス",
#=> created_at: Wed, 24 Aug 2022 03:13:14.155937000 UTC +00:00,
#=> updated_at: Wed, 24 Aug 2022 03:13:14.155937000 UTC +00:00>,
#=> 4=>
#=> #<Category:0x0000562b92c96f80
#=> id: 4,
#=> book_id: 2,
#=> name: "自己啓発",
#=> created_at: Wed, 24 Aug 2022 03:13:21.284702000 UTC +00:00,
#=> updated_at: Wed, 24 Aug 2022 03:13:21.284702000 UTC +00:00>
#=> }
index_by メソッドの引数はブロックなのでキーの加工も可能
categories = Category.all.index_by { |c| "category_#{c.id}" }
#=> {
#=> "category_1"=>
#=> #<Category:0x0000562b9325f598
#=> id: 1,
#=> book_id: 1,
#=> name: "少年誌",
#=> created_at: Wed, 24 Aug 2022 02:54:05.711796000 UTC +00:00,
#=> updated_at: Wed, 24 Aug 2022 02:54:05.711796000 UTC +00:00>,
#=> "category_2"=>
#=> #<Category:0x0000562b9325f4d0
#=> id: 2,
#=> book_id: 1,
#=> name: "青年誌",
#=> created_at: Wed, 24 Aug 2022 02:54:45.283884000 UTC +00:00,
#=> updated_at: Wed, 24 Aug 2022 02:54:45.283884000 UTC +00:00>,
#=> "category_3"=>
#=> #<Category:0x0000562b9325f3e0
#=> id: 3,
#=> book_id: 2,
#=> name: "ビジネス",
#=> created_at: Wed, 24 Aug 2022 03:13:14.155937000 UTC +00:00,
#=> updated_at: Wed, 24 Aug 2022 03:13:14.155937000 UTC +00:00>,
#=> "category_4"=>
#=> #<Category:0x0000562b9325f318
#=> id: 4,
#=> book_id: 2,
#=> name: "自己啓発",
#=> created_at: Wed, 24 Aug 2022 03:13:21.284702000 UTC +00:00,
#=> updated_at: Wed, 24 Aug 2022 03:13:21.284702000 UTC +00:00>
#=> }
value の方も加工したい場合には inject メソッドを使用する
categories = Category.all.inject({}) do |hash, c|
hash[c.id] = c.name
hash
end
#=> {1=>"少年誌", 2=>"青年誌", 3=>"ビジネス", 4=>"自己啓発"}
ちなみに上記のような出し方がしたいのであれば下記でも良い
categories = Category.all.pluck(:id, :name).to_h
#=> {1=>"少年誌", 2=>"青年誌", 3=>"ビジネス", 4=>"自己啓発"}