Railsでモデルを抽出する時に使う ActiveRecord::Relation
の select
, pluck
, group
, having
についてまとめました
artist
モデルを作成rails g model artist name:string
# artist.rb
class Artist < ApplicationRecord
has_many :albums
end
album
モデルを artist
の子モデルとして作成rails g model album title:string artist:references
# album.rb
class Album < ApplicationRecord
has_many :albums
belongs_to :artist
end
song
モデルを album
の子モデルとして作成rails g model song title:string producer:string album:references
# song.rb
classSong< ApplicationRecord
belongs_to :album
end
モデルの属性の中で取得したい属性を指定し、対象のインスタンス配列を作成する
属性は複数指定もできる
Artist.select(:name, :created_at)
# SELECT "artists"."name", "artists"."created_at" FROM "artists"
select
と似たような使い方ができるが、 select
がインスタンス配列を返すのに対し、 pluck
は抽出した属性のみの配列となる
返り値が String
の配列になるので ActiceRecord::Relation
インスタンスのメソッドが使えなくなるので注意
Artist.pluck(:name, :created_at)
# SELECT "artists"."name", "artists"."created_at" FROM "artists"
#=> [["2pac", Mon, 14 Jun 2021 05:24:45.290303000 UTC +00:00], ["The Weeknd", Mon, 14 Jun 2021 05:24:45.290303000 UTC +00:00], ["Nas", Mon, 14 Jun 2021 05:24:45.290303000 UTC +00:00]]
指定された属性でグループ化する
グループ化した属性を count
, sum
, average
メソッドなどでハッシュとして参照できる
Song.group(:producer).select(:title, :producer)
# SELECT "songs"."title", "songs"."producer" FROM "songs" GROUP BY "songs"."producer"
# Songモデルをproducer属性でグループ化し、titleとproducerのみ抽出する
Song.group(:producer).count
#=> {"DJ Premier"=>4, "Dr.Dre"=>1, "L.E.S"=>3, "Large Professor"=>3, "Pete Rock"=>1, "Q-Tip"=>1, "nil"=>1}
group化したものに対して引数に条件を渡して抽出する
Song.group(:producer).having(producer: 'DJ Premier').count
# SELECT COUNT(*) AS count_all, "songs"."producer" AS songs_producer FROM "songs" GROUP BY "songs"."producer" HAVING "songs"."producer" = ? [["producer", "DJ Premier"]]
# {"DJ Premier"=>4}
(参考)