gpt4 book ai didi

ruby-on-rails - Rails 加入关联限制

转载 作者:行者123 更新时间:2023-11-29 11:25:13 24 4
gpt4 key购买 nike

我正在尝试查询所有Stations,并加入Measures

但我只想要最近的测量值(按 created_at DESC 排序),因为一个站有数千个测量值。

我试过了

Station.joins(:measures).limit(1) 

但这只是限制了站点。

附加信息:

Station有很多Measures

Measure 属于Station

我已经通读了 Active Records docs并且只有关于在关联上使用 where 条件的信息。

该应用程序仅针对 Postgres,接受 SQL。


编辑:除了 schema.rb 添加:

  create_table "measures", force: true do |t|
t.integer "station_id"
t.float "speed"
t.float "direction"
t.float "max_wind_speed"
t.float "min_wind_speed"
t.float "temperature"
t.datetime "created_at"
t.datetime "updated_at"
t.float "speed_calibration"
end

add_index "observations", ["created_at"], name: "index_observations_on_created_at", using: :btree
add_index "observations", ["station_id"], name: "index_observations_on_station_id", using: :btree

create_table "stations", force: true do |t|
t.string "name"
t.string "hw_id"
t.float "latitude"
t.float "longitude"
t.float "balance"
t.boolean "offline"
t.string "timezone"
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
t.string "slug"
t.boolean "show", default: true
t.float "speed_calibration", default: 1.0
t.datetime "last_observation_received_at"
end

添加这是目前正在使用的非常骇人听闻的代码:

def all_with_latest_measure
if user_signed_in? && current_user.has_role?(:admin)
stations = Station.all.load
end
stations ||= Station.where(show: true).load

if stations.size
ids = stations.map { |s| s.id }.join(',')
where = "WHERE m.station_id IN(#{ids})" unless ids.empty?
measures = Measure.find_by_sql(%Q{
SELECT DISTINCT ON(m.station_id, m.created_at)
m.*
FROM measures m
#{where}
ORDER BY m.created_at DESC
})

stations.each do |station|
# Setup has_many relationship between station and Measure
# Prevents n+1 queries
measure = Measures.find { |m| m.station_id == station.id }
if measure
measure.station = station
station.latest_measure = measure
end
end
end
end

最佳答案

我相信在 Rails 4 中你可以在关联上应用范围:

class Stations
has_many :measures, -> { order('created_at DESC').limit(1) }
end

然后:

2.0.0-p353 :008 > Station.first.measures
Station Load (0.1ms) SELECT "stations".* FROM "stations" ORDER BY "stations"."id" ASC LIMIT 1
Measure Load (0.1ms) SELECT "measures".* FROM "measures" WHERE "measures"."station_id" = ? ORDER BY created_at DESC LIMIT 1 [["station_id", 1]]

编辑:实际上,如果您只需要最新的一个,您可以使用 has_one。它适用于 Rails 4 和 Rails 3,语法略有修改:

class Stations
has_one :recent_measure, -> { order('created_at DESC') }, class_name: 'Measure' # Rails 4
has_one :recent_measure, order: 'created_at DESC', class_name: 'Measure' # Rails 3
end

关于ruby-on-rails - Rails 加入关联限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21878485/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com