在rails查询上优化ruby

时间:2015-12-22 12:53:11

标签: ruby-on-rails ruby

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

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

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 :(得分:0)

关注@sergio和Guide 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 Eager Loading Associations Includes

的更多信息

答案 1 :(得分:-1)

更新

在我原来的答案中,我完全错过了AddressSetup是不同的关系。所以这是最新的答案!

主要问题,“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