📅  2021-06-14

ActiveRecord::Relationの使い方

🔖Ruby on Rails🔖SQL

Railsでモデルを抽出する時に使う ActiveRecord::Relationselect , pluck , group , having についてまとめました

rails g model artist name:string
# artist.rb
class Artist < ApplicationRecord
  has_many :albums
end

rails g model album title:string artist:references
# album.rb
class Album < ApplicationRecord
  has_many :albums
  belongs_to :artist
end

rails g model song title:string producer:string album:references
# song.rb
classSong< ApplicationRecord
  belongs_to :album
end

Artistテーブル

image in the content

Albumテーブル

image in the content

Songテーブル

image in the content

select

モデルの属性の中で取得したい属性を指定し、対象のインスタンス配列を作成する

属性は複数指定もできる

Artist.select(:name, :created_at)
# SELECT "artists"."name", "artists"."created_at" FROM "artists"
image in the content

pluck

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]]

group

指定された属性でグループ化する グループ化した属性を count, sum , average メソッドなどでハッシュとして参照できる

Song.group(:producer).select(:title, :producer)
# SELECT "songs"."title", "songs"."producer" FROM "songs" GROUP BY "songs"."producer"
# Songモデルをproducer属性でグループ化し、titleとproducerのみ抽出する
image in the content
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}

having

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}

(参考)

Railsのクエリインタフェース select、where、or、mergeメソッドの使い方 - Qiita

タグ