Rails查询子类并限制每个子类

时间:2017-11-12 16:56:15

标签: ruby-on-rails rails-activerecord

我有一个artifacts表,用于保存下载的文件。每种类型都包含不同的数据

class Artifact < ActiveRecord::Base
end

class ForecastArtifact < Artifact
end

class ChargebackArtifact < Artifact
end

class CatalogArtifact < Artifact
end

对于单个帐户,我正在查询每种工件类型的最新内容:

  artifact_types = Artifact.subclasses.map(&:to_s)

  artifacts_for_account = artifact_types.map do |type|
    @account.artifacts
            .where(type: type)
            .order("valid_as_of DESC")
            .limit(1).first
            .as_json({only: [:id, :account_id, :type]})
  end

不幸的是,这会进行N次查询。

你会为此做一个查询吗?更多的轨道式解决这个问题?

1 个答案:

答案 0 :(得分:0)

如果您正在使用PostgreSQL,可以使用DISTINCT ON来解决此问题:

>> a = Account.last
  Account Load (0.4ms)  SELECT  "accounts".* FROM "accounts" ORDER BY "accounts"."id" DESC LIMIT $1  [["LIMIT", 1]]
=> #<Account id: 1, created_at: "2017-11-17 17:16:03", updated_at: "2017-11-17 17:16:03">

>> a.artifacts.select("distinct on (type) valid_as_of, type, id").group(:type, :valid_as_of, :id).order(:type, valid_as_of: :desc)
  Artifact Load (0.6ms)  SELECT  distinct on (type) valid_as_of, type, id FROM "artifacts" WHERE "artifacts"."account_id" = $1 GROUP BY "artifacts"."type", "artifacts"."valid_as_of", "artifacts"."id" ORDER BY "artifacts"."type" ASC, "artifacts"."valid_as_of" DESC LIMIT $2  [["account_id", 1], ["LIMIT", 11]]
=> #<ActiveRecord::AssociationRelation [#<ChargebackArtifact id: 22, type: "ChargebackArtifact", valid_as_of: "2017-11-17 17:06:03">, #<ForecastArtifact id: 21, type: "ForecastArtifact", valid_as_of: "2017-11-17 17:11:03">]>

每个帐户只需要一个查询。