所以在我过去的应用程序中,我对在Rails中使用.includes
有些熟悉,但由于某种原因,我在当前场景中遇到了一些困难。
以下是我正在使用的内容:
# If non-existent, create. Otherwise, update.
existing_data = Page.all
updated_data = {}
new_records = []
@latest_page_data.each do |key, value|
existing_record = existing_data.find_by(symbol: key)
if existing_record != nil
updated_data[existing_record.id] = value
else
new_records << Page.new(value)
end
end
if !new_records.empty?
Page.import new_reocrds
end
if !updated_data.empty?
Page.update(updated_data.keys, updated_data.values)
end
end
我遇到的问题是代码的.find_by
部分导致每@latest_page_data
次迭代的查询。我想我会认为existing_data会在内存中保存所需的所有数据,但显然它不会那样工作。
接下来,我尝试过这样的事情:
# If non-existent, create. Otherwise, update.
existing_data = Page.includes(:id, :symbol)
updated_data = {}
new_records = []
@latest_currency_data.each do |key, value|
existing_record = existing_data.find_by(symbol: key)
但是rails会抛出一个错误,说明:
ActiveRecord :: AssociationNotFoundError(名为&#39; id&#39;的关联不是 在页面上找到;也许你拼错了吗?):
所以我无法使用此示例来查找id
和symbol
属性。
我尝试在:id
方法中取出Page.includes
,但我需要能够获取ID属性,以便稍后在代码中更新相应的记录。
我还看到了其他一些与此主题有关的帖子,但我认为我可能遇到的问题是我没有处理关联(而且我相信这是{{{{ 1}}是为了?如果是这种情况,还有其他方法可以减少我在这里提交的所有查询吗?
答案 0 :(得分:2)
includes
方法用于预加载关联模型。我认为你要找的是select
。修改您的代码以使用select
,请执行以下操作:
existing_data = Page.select(:id, :symbol).load
updated_data = {}
new_records = []
@latest_currency_data.each do |key, value|
existing_record = existing_data.find_by(symbol: key)
if existing_record
updated_data[existing_record.id] = value
else
new_records << Page.new(value)
end
end
使用
select
而不是pluck
的缺点是,由于Rails为您构造了一个对象,因此它比pluck
慢。 Benchmark: pluck vs select
答案 1 :(得分:1)
我没有试图在Rails中找到一种方法(因为我不熟悉100%正确/准确的Rails方式),我只是决定使用.pluck
并将其转换为哈希获取我正在寻找的数据:
existing_data = Page.pluck(:id, :symbol)
existing_data = Hash[*existing_data.flatten]
updated_data = {}
new_records = []
@latest_currency_data.each do |key, value|
if existing_data.values.include? key
id = existing_data.find{|k,v| v.include? key}[0]
updated_data[id] = value
else
new_records << Page.new(value)
end
end
如果有人有更好的方式,我们将很高兴地感激不尽。谢谢!