ruby-on-rails-3 – 用arel中的union重写复杂的查询?

我有以下型号

class Courier < ActiveRecord::Base
  has_many :coverages
end

class Coverage < ActiveRecord::Base
  belongs_to :courier
  belongs_to :country_code
end

class CountryCode < ActiveRecord::Base      
end

然后我有以下查询:

# could i translate this into cleaner arel?
result = Courier.find_by_sql(<<SQL
          select * from
          (
            select cc.*, cv.rate from couriers cc, coverages cv
            where cv.country_code_id=#{country.id} and cv.courier_id=cc.id
          union
            select cc.*, cv.rate from couriers cc, coverages cv
            where cv.country_code_id is null
              and cv.courier_id=cc.id
              and cv.courier_id not in (select courier_id from coverages where country_code_id=#{country.id})
          ) as foo order by rate asc
SQL
)

简而言之:我正在寻找覆盖给定国家/地区代码或覆盖空国家代码的所有快递公司(后备).

该查询有效,但我想知道是否有更好的方法来编写它?

最佳答案 如果你想保留find_by_sql,你可以将查询压缩成:

result = Courier.find_by_sql [
  "SELECT cc.*, cv.rate
  FROM couriers cc inner join coverages cv on cv.courier_id = cc.id
  WHERE cv.country_code_id = ?
    OR (cv.country_code_id is null AND cv.courier_id NOT IN (SELECT courier_id FROM coverages WHERE country_code_id= ? ))
  ORDER BY cv.rate asc", country.id, country.id ]
点赞