1. shibadai

    Posted

    shibadai
Changes in title
+配列をActiveRecord::Relationに変換するメソッドを作ってみる
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,158 @@
+Rubyなどで使える`map、reject、select`などのメソッドはとても便利だがRailsの`User.all`なんかで取得したデータにこれを使うとActiveRecord::RelationクラスがただのArrayクラスになってしまい困った事態に陥りやすい。
+
+(下記例)
+
+```rb
+[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
+```
+
+
+```rb
+[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.class`が`User::ActiveRecord_Relation`だったのが、mapなどを経由すると単なる`Array`になってしまう。
+こうなると、ActiveRecord_Relationのメソッドがうまく使えなくなったり、自分の場合はRansackの検索機能がきかなくなって頭を抱えた。
+
+そんな時に、下記の記事が非常に助けになった。
+
+https://qiita.com/wada811/items/12c74ed62c943c8c3f77
+
+(コードだけ一部抜粋)
+
+```rb
+# items = [#<Item>, #<Item>, #<Item>]
+@items = Item.where(id: items.map{ |item| item.id })
+```
+
+上記のようにすれば配列からActiveRecord::Relationにクラスを戻すことができる。
+なるほど!頭いい!!と思って、自分もありがたくこの解法を使わせてもらった。
+
+しかし、`map`や`reject`を使うたびにこのメソッドを記述するのは面倒臭い。
+
+というわけで、下記のようなクラス復元メソッドを定義してみた。
+
+```rb
+def revive_active_record(arr)
+ arr.first.class.where(id: arr.map(&:id))
+end
+```
+
+さっそく試してみる(試しかたは適当です。。。( 'ω' ))
+
+```rb
+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 "=================================================="
+```
+
+```rb
+"=================================================="
+ 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
+"=================================================="
+```
+
+特に問題なさそう。