43
28

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

配列をActiveRecord::Relationで再取得するメソッドを作ってみる

Last updated at Posted at 2018-06-07

Rubyなどで使えるmap、reject、selectなどのメソッドはとても便利だがRailsのUser.allなんかで取得したデータにこれを使うとActiveRecord::RelationクラスがただのArrayクラスになってしまい困った事態に陥りやすい。

(下記例)

[1] pry(main)> User.all
  User Load (0.9ms)  SELECT "users".* FROM "users"
=> [#<User:0x007fdf164cea08
  id: 1,
  name: "xxxxxxxxxxxxx92",
  image: "http://pbs.twimg.com/profile_images/830018730490896385/BDAl65j1_normal.jpg",
  uid: "829207717483012099",
  string: "",
  provider: "twitter",
  created_at: Tue, 05 Jun 2018 20:14:45 JST +09:00,
  updated_at: Tue, 05 Jun 2018 20:14:45 JST +09:00,
  upload_image: nil>,
 #<User:0x007fdf164c4058
  id: 2,
  name: "xxxxxxxxxxxxx",
  image: "https://avatars3.githubusercontent.com/u/25131575?v=4",
  uid: "25131575",
  string: "",
  provider: "github",
  created_at: Tue, 05 Jun 2018 20:14:54 JST +09:00,
  updated_at: Tue, 05 Jun 2018 20:14:54 JST +09:00,
  upload_image: nil>]

[2] pry(main)> User.all.class
=> User::ActiveRecord_Relation
[3] pry(main)> User.all.map{|user| user }
  User Load (1.7ms)  SELECT "users".* FROM "users"
=> [#<User:0x007fdf16456cb0
  id: 1,
  name: "xxxxxxxxxxxxx92",
  image: "http://pbs.twimg.com/profile_images/830018730490896385/BDAl65j1_normal.jpg",
  uid: "829207717483012099",
  string: "",
  provider: "twitter",
  created_at: Tue, 05 Jun 2018 20:14:45 JST +09:00,
  updated_at: Tue, 05 Jun 2018 20:14:45 JST +09:00,
  upload_image: nil>,
 #<User:0x007fdf16456b70
  id: 2,
  name: "xxxxxxxxxxxxx",
  image: "https://avatars3.githubusercontent.com/u/25131575?v=4",
  uid: "25131575",
  string: "",
  provider: "github",
  created_at: Tue, 05 Jun 2018 20:14:54 JST +09:00,
  updated_at: Tue, 05 Jun 2018 20:14:54 JST +09:00,
  upload_image: nil>]

[4] pry(main)> User.all.map{|user| user }.class
  User Load (0.5ms)  SELECT "users".* FROM "users"
=> Array

このように、User.all.classUser::ActiveRecord_Relationだったのが、mapなどを経由すると単なるArrayになってしまう。
こうなると、ActiveRecord_Relationのメソッドがうまく使えなくなったり、自分の場合はRansackでエラーが出たりして頭を抱えた。

そんな時に、下記の記事が非常に助けになった。

(コード部分だけ抜粋)

# items = [#<Item>, #<Item>, #<Item>]
@items = Item.where(id: items.map{ |item| item.id })

上記のようにすれば配列からActiveRecord::Relationにクラスを戻すことができる。
なるほど!頭いい!!と思って、自分もありがたくこの解法を使わせてもらった。

しかし、maprejectを使うたびにこのメソッドを記述するのは面倒臭い。

というわけで、下記のようなクラス復元メソッドを定義してみた。

def revive_active_record(arr)
  arr.first.class.where(id: arr.map(&:id))
end

さっそく試してみる(試しかたは適当です。。。( 'ω' ))

pp "=================================================="
pp arr=User.all.map{ |user| user }
pp "=================================================="
pp arr.class
pp "=================================================="
pp revive_active_record(arr)
pp "=================================================="
pp revive_active_record(arr).class
pp "=================================================="
"=================================================="
  User Load (0.3ms)  SELECT "users".* FROM "users"
[#<User:0x007fc335f73b68
  id: 1,
  name: "xxxxxxxxxxxxx92",
  image:
   "http://pbs.twimg.com/profile_images/830018730490896385/BDAl65j1_normal.jpg",
  uid: "829207717483012099",
  string: "",
  provider: "twitter",
  created_at: Tue, 05 Jun 2018 20:14:45 JST +09:00,
  updated_at: Tue, 05 Jun 2018 20:14:45 JST +09:00,
  upload_image: nil>,
 #<User:0x007fc335f734b0
  id: 2,
  name: "xxxxxxxxxxxxx",
  image: "https://avatars3.githubusercontent.com/u/25131575?v=4",
  uid: "25131575",
  string: "",
  provider: "github",
  created_at: Tue, 05 Jun 2018 20:14:54 JST +09:00,
  updated_at: Tue, 05 Jun 2018 20:14:54 JST +09:00,
  upload_image: nil>]
"=================================================="
Array
"=================================================="
  User Load (4.1ms)  SELECT "users".* FROM "users" WHERE "users"."id" IN (1, 2)
[#<User:0x007fc335e79000
  id: 1,
  name: "xxxxxxxxxxxxx92",
  image:
   "http://pbs.twimg.com/profile_images/830018730490896385/BDAl65j1_normal.jpg",
  uid: "829207717483012099",
  string: "",
  provider: "twitter",
  created_at: Tue, 05 Jun 2018 20:14:45 JST +09:00,
  updated_at: Tue, 05 Jun 2018 20:14:45 JST +09:00,
  upload_image: nil>,
 #<User:0x007fc335e78448
  id: 2,
  name: "xxxxxxxxxxxxx",
  image: "https://avatars3.githubusercontent.com/u/25131575?v=4",
  uid: "25131575",
  string: "",
  provider: "github",
  created_at: Tue, 05 Jun 2018 20:14:54 JST +09:00,
  updated_at: Tue, 05 Jun 2018 20:14:54 JST +09:00,
  upload_image: nil>]
"=================================================="
User::ActiveRecord_Relation
"=================================================="

特に問題なさそう。
(その役割なら、すでにあるこのメソッドでできるよとかあったら、ご教授いただけると嬉しいですm(__)m)

43
28
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
43
28

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?