如何在Rails中基于外键列选择唯一记录?

时间:2014-10-19 07:52:39

标签: ruby-on-rails database ruby-on-rails-3 postgresql activerecord

我的Rails 4.1应用程序中有以下模型结构:

delivery_service.rb

class DeliveryService < ActiveRecord::Base
    attr_accessible :name, :description, :courier_name, :active, :country_ids

    has_many :prices, class_name: 'DeliveryServicePrice', dependent: :delete_all
end

delivery_service_price.rb

class DeliveryServicePrice < ActiveRecord::Base

  attr_accessible :code, :price, :description, :min_weight, :max_weight, :min_length, :max_length, 
  :min_thickness, :max_thickness, :active, :delivery_service_id

  belongs_to :delivery_service
end

如您所见,送货服务有很多送货服务价格。我试图从送货服务价格表中检索记录; 选择外键唯一范围内价格属性最低的记录,delivery_service_id(基本上是每个送货服务最便宜的送货服务价格)。

如何使用外键属性作为范围从表中选择唯一记录?

我希望我已经解释了这一点,如果您需要更多信息,请告诉我。

由于

更新#1:

我想要实现的目标的例子:

delivery_service_prices表:

id:1,价格:2.20,delivery_service_id:1

id:2,价格:10.58,delivery_service_id:1

id:3,价格:4.88,delivery_service_id:2

id:4,价格:1.20,delivery_service_id:2

id:5,价格:14.99,delivery_service_id:3

预期结果:

id:1,价格:2.20,delivery_service_id:1

id:4,价格:1.20,delivery_service_id:2

id:5,价格:14.99,delivery_service_id:3

2 个答案:

答案 0 :(得分:2)

由于PostgreSQL对遵守SQL标准更加严格(正确地说是这样),因此需要进行一些调整才能获得正确的结果。

以下查询返回每个送货服务的最低送货服务价格的正确结果:

DeliveryServicePrice.select('DISTINCT ON (delivery_service_id) *').order('delivery_service_id, price ASC')

我需要将 delivery_service_id 属性添加到订单条件中,否则PostgreSQL会抛出以下列错误:

PG::InvalidColumnReference: ERROR:  SELECT DISTINCT ON expressions must match initial ORDER BY expressions

希望这有助于任何偶然发现它的人!

答案 1 :(得分:0)

要获得单个记录的最小值,您可以使用

DeliveryServicePrice.where(delivery_service_id: x).order(:price).limit(1).first

或者如果您有delivery_service个对象

delivery_service.prices.order(:price).limit(1).first

更新

如果您想要所有service_delivery_id的所有最低要求,可以使用group查询

DeliveryServicePrice.group(:delivery_service_id).minimum(:price)

这将使你几乎到达你想去的地方

{
  1: 2.20,
  2: 1.20,
  3: 14.99
}

使用包含delivery_service_id和价格的哈希。 (你不能看到price_id)