标题很混乱,但让我解释一下。我有一个车型有多个数据点,具有不同的时间戳。我们几乎总是关心其最新状态的属性。因此模型的has_many状态,具有HAS_ONE一起轻松访问其最新一个:Rails 3 has_one关联的一个查询匹配属性has_many association的子集
class Car < ActiveRecord::Base
has_many :statuses, class_name: 'CarStatus', order: "timestamp DESC"
has_one :latest_status, class_name: 'CarStatus', order: "timestamp DESC"
delegate :location, :timestamp, to: 'latest_status', prefix: 'latest', allow_nil: true
# ...
end
为了让你的状态保持什么样的想法:
loc = Car.first.latest_location # Location object (id = 1 for example)
loc.name # "Miami, FL"
比方说,我想有一个(可链接)范围,找到为1。最新的位置ID的所有汽车目前我有一种复杂的方法:
# car.rb
def self.by_location_id(id)
ids = []
find_each(include: :latest_status) do |car|
ids << car.id if car.latest_status.try(:location_id) == id.to_i
end
where("id in (?)", ids)
end
有可能做到这一点使用SQL更快的方法,但不知道如何只得到l每辆车的最佳状态。可能有许多状态记录的location_id为1,但如果这不是其最新的位置,则不应包含它。
为了让它更难...让我们添加另一个级别,并能够通过位置名称进行范围。我有这样的方法,以及它们的位置对象一起预压状态,以便能够访问名字:
def by_location_name(loc)
ids = []
find_each(include: {latest_status: :location}) do |car|
ids << car.id if car.latest_location.try(:name) =~ /#{loc}/i
end
where("id in (?)", ids)
end
这将“迈阿密”,“FL”,“MIA”等相匹配的上面的位置...有没有人有任何建议,我可以如何使这个更简洁/高效?以不同的方式定义我的关联会更好吗?或者,也许它会采取一些SQL忍者技能,我承认没有。
使用Postgres 9.1(托管在Heroku雪松堆栈上)
我有一种感觉,你的问题的有效解决方案将有点数据库特定。你能否把你的数据库的名称和版本添加到问题中? – MrTheWalrus 2012-08-01 17:40:04
@MrTheWalrus良好的调用,我使用Heroku雪松堆栈与Postgres 9.1 – 2012-08-02 01:22:09
将最新状态和旧状态保存在单独的表中可能会更容易。这样你仍然有你的历史,但你没有困难查询。有点相关:http://stackoverflow.com/questions/762405/database-data-versioning – Mischa 2012-08-02 02:41:23