Quantcast
Channel: hachi8833の記事一覧|TechRacho by BPS株式会社
Viewing all articles
Browse latest Browse all 1759

Rails 6.1: 関連付けのあるレコードを取れる’associated’クエリメソッドが追加(翻訳)

$
0
0

概要

原著者の許諾を得て翻訳・公開いたします。

日本語タイトルは内容に即したものにしました。

以下の関連記事もどうぞ。

Rails 6.1: 関連付けのあるレコードを取れるassociatedクエリメソッドが追加(翻訳)

Rails 6.1で、ActiveRecord::Relation#missingに似たassociatedというクエリメソッドが追加されました(#40696)。missingは孤立化したオブジェクトのリストを取れるActiveRecord::Relationを返すので、孤立化したオブジェクトが存在するかどうかをチェックできます。associatedは関連付けが存在するオブジェクトのリストを取れるActiveRecord::Relationを返すので、関連付けのあるオブジェクトが存在するかどうかをチェックできます。

以下の3つのモデルで考えてみましょう。

# app/models/manager.rb
# Manager: 担当管理職
class Manager < ApplicationRecord
  has_many :job_listings
end
# app/models/job_listing.rb
# JobListing: 求職リスト
class JobListing < ApplicationRecord
  has_many :job_applications
  belongs_to :manager
end
# app/models/job_application.rb
# JobApplication: 求職への応募
class JobApplication < ApplicationRecord
  belongs_to :job_listing
end

Rails 6.1より前

担当管理職を参照できる求職リストをすべて検索するときは、以下のように行っていました。

[1] pry(main)> JobListing.joins(:manager).where.not(managers: {id: nil})
JobListing Load (0.2ms)  SELECT "job_listings".* FROM "job_listings"
INNER JOIN "managers" ON "managers"."id" = "job_listings"."manager_id"
WHERE "managers"."id" IS NOT NULL LIMIT ?  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Manager id: 3, name: "Jane Doe", created_at: "2020-01-20 14:31:16", updated_at: "2020-01-20 14:31:16">]>

Rails 6.1以後

Rails 6.1のActiveRecord::QueryMethods::WhereChainクラスにassociatedクエリメソッドが追加されました(#40696)。

上述の例を用いて、担当管理職を参照可能な求職リストをすべて検索してみましょう。

[1] pry(main)> JobListing.where.associated(:manager)
JobListing Load (0.1ms)  SELECT "job_listings".* FROM "job_listings"
INNER JOIN "managers" ON "managers"."id" = "job_listings"."manager_id"
WHERE "managers"."id" IS NOT NULL LIMIT ?  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Manager id: 3, name: "Jane Doe", created_at: "2020-01-20 14:31:16", updated_at: "2020-01-20 14:31:16">]>
[2] pry(main)>

associatedは単なるシンタックスシュガーです。理由は、先の例と同様に存在チェックを行うINNER JOIN句とWHERE句を含むリレーション(ActiveRecord::Relation)を返すからです。

associatedにはリレーション名を複数渡すことも可能です。

たとえば、担当管理職と応募のどちらも参照可能な求職リストを検索するには以下のようにします。

[1] pry(main)> JobListing.where.associated(:manager, :job_applications)
JobListing Load (0.1ms)  SELECT "job_listings".* FROM "job_listings"
INNER JOIN "managers" ON "managers"."id" = "job_listings"."manager_id"
INNER JOIN "job_applications" ON "job_applications"."job_listing_id" = "job_listings"."id"
WHERE "managers"."id" IS NOT NULL AND "job_applications"."id" IS NOT NULL LIMIT ?  [["LIMIT", 11]]
  => #<ActiveRecord::Relation []>
[2] pry(main)>

このコード例では、担当管理職を参照可能な求職リストが存在する場合でも空のリレーション(#<ActiveRecord::Relation []>)が返されました。理由は、この求職リストから参照できる応募が存在しなかったからです。

関連記事

Rails 6.1: 孤立化したレコードのリストを取れる’missing’クエリメソッドが追加(翻訳)

Rails 6.1で form_withのデフォルトが「remoteなし」に戻った(翻訳)


Viewing all articles
Browse latest Browse all 1759

Trending Articles