优化Ruby on Rails查询

3

我的应用程序在几个页面上都有一个带有许多标记的地图。

因此,我在控制器中发送带有坐标的哈希表到视图。

setups = current_user.setups
coordinates_hash = Hash.new { |hsh, key| hsh[key] = {} }
setups.each do |i|
  if i.address.lat != nil && i.address.long != nil
    lat = i.address.lat
    long = i.address.long
    coordinates_hash[i.setup_id].store 'lat', lat
    coordinates_hash[i.setup_id].store 'long', long
  end
end

因此,在我的视图中,我收到了这个哈希值

var coordenadas = <%= raw(@coordinates_hash.to_json) %>;

我该如何优化这个过程?
2个回答

0

在关注 @sergio 和 Ruby on Rails指南 后,您可以像这样更改您的代码

coordinates_hash = Hash.new { |hsh, key| hsh[key] = {} }

setups = current_user.setups.includes(:address)

setups.each do |i|
  if i.address.lat.present?  && i.address.long.present?
    coordinates_hash[i.setup_id].store 'lat', i.address.lat
    coordinates_hash[i.setup_id].store 'long',  i.address.long
  end
end

点击此处了解更多关于 ActiveRecord 预加载关联 Includes的内容。


-2

更新

在我的原始答案中,我完全忽略了地址设置是不同的关系。所以这里是最新的答案!

主要问题,“N+1查询”可以通过两种方式解决:

1)急切地加载所有地址

setups = current_user.setups.includes(:addresses)

这将加载所有设置的地址。然而,我们只需要具有latlong的地址。

2) 连接查询

首先,在您的User模型中添加以下行:

has_many :addresses, through: :setups

这使你能够做到这一点:

current_user.addresses.where('lat is not null and long is not null')

这会导致单个查询。

最终结果:

@coordinates = {}

addresses = current_user.addresses
          .where('lat is not null and long is not null')
          .select(:lat, :long)

addresses.each do |address|
  @coordinates[address.setup_id] = address.slice(:lat, :long)
end

1
你错过了 N+1 查询。 - Sergio Tulentsev
@SergioTulentsev 哎呀,我做到了! - mhutter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接