如何编写最有效的范围,仅询问那些具有某些子对象的父对象

时间:2012-04-30 11:02:43

标签: ruby-on-rails ruby ruby-on-rails-3 activerecord arel

我有:

class Evaluation < ActiveRecord::Base
  has_many :scores
end
class Score < ActiveRecord::Base
  scope :for_disability_and_score,
        lambda { |disability, score|
          where('total_score >= ? AND name = ?', score, disability)
        }
end

scores表格包含total_score字段和name字段。

我如何撰写scope只询问那些evaluations Score名称为'vision'且total_score为2且又有Score total_score的{​​{1}} 1}}名称为“听力”,I managed to do it in raw sql: sql = %q-SELECT "evaluations".* FROM "evaluations" INNER JOIN "scores" AS s1 ON "s1"."evaluation_id" = "evaluations"."id" INNER JOIN "target_disabilities" AS t1 ON "t1"."id" = "s1"."target_disability_id" INNER JOIN "scores" AS s2 ON "s2"."evaluation_id" = "evaluations"."id" INNER JOIN "target_disabilities" AS t2 ON "t2"."id" = "s2"."target_disability_id" WHERE "t1"."name" = 'vision' AND (s1.total_score >= 1) AND "t2"."name" = 'hearing' AND (s2.total_score >= 2)- 为3。 如何将所有这些推广到要求那些在我的参数中得分为n的评估?

在原始sql中它就像:

INNER JOIN "scores" AS s1 ON "s1"."evaluation_id" = "evaluations"."id"

这里重点是:

WHERE (s1.total_score >= 1)

和(通过将s1替换为s2和s3等等):

{{1}}

但它应该是这样做的轨道方式...... :)希望

1 个答案:

答案 0 :(得分:0)

试试这个:

scope :by_scores, lambda do |params|
    if params.is_a? Hash
      query = joins(:scores)
      params.each_pair do |name, score|
        query = query.where( 'scores.total_score >= ? AND scores.name = ?', score, name)
      end
      query
    end
 end

然后这样打电话:

Evaluation.by_scores 'vision' => 2, 'hearing' => 3