Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
28
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

Organization

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

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)

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
28
Help us understand the problem. What are the problem?