1. ホーム
  2. sql

[解決済み] アソシエーションのカウントが0より大きいレコードをすべて検索する

2022-05-16 13:22:46

質問

簡単なことだと思っていたのですが、そうではなさそうです。

私は多くの欠員があるプロジェクトモデルを持っています。

class Project < ActiveRecord::Base

  has_many :vacancies, :dependent => :destroy

end

私は少なくとも1つの空室を持つすべてのプロジェクトを取得したいです。 こんな感じでやってみました。

Project.joins(:vacancies).where('count(vacancies) > 0')

と書いてありますが

SQLite3::SQLException: no such column: vacancies: SELECT "projects".* FROM "projects" INNER JOIN "vacancies" ON "vacancies"."project_id" = "projects"."id" WHERE ("projects"."deleted_at" IS NULL) AND (count(vacancies) > 0) .

どのように解決するのですか?

joins はデフォルトで内部結合を使用するので Project.joins(:vacancies) を使用すると、事実上、関連する空室を持つプロジェクトのみを返します。

UPDATE

コメントで @mackskatz さんから指摘があったように group 節がない場合、上記のコードでは、複数の空きがあるプロジェクトについて、重複したプロジェクトが返されます。 重複を削除するには

Project.joins(:vacancies).group('projects.id')

UPDATE

また、@Tolsee さんのご指摘のように distinct .

Project.joins(:vacancies).distinct

例として

[10] pry(main)> Comment.distinct.pluck :article_id
=> [43, 34, 45, 55, 17, 19, 1, 3, 4, 18, 44, 5, 13, 22, 16, 6, 53]
[11] pry(main)> _.size
=> 17
[12] pry(main)> Article.joins(:comments).size
=> 45
[13] pry(main)> Article.joins(:comments).distinct.size
=> 17
[14] pry(main)> Article.joins(:comments).distinct.to_sql
=> "SELECT DISTINCT \"articles\".* FROM \"articles\" INNER JOIN \"comments\" ON \"comments\".\"article_id\" = \"articles\".\"id\""