我有一个ActiveAdmin资源,其集合需要一些特别复杂的查询以避免一堆n + 1。我试图用所有正确的.includes或.joins修改控制器#scoped_collection,但它仍然在做n + 1。
我已经改为采用手工执行查询并将相关结果转储到Hashes中的方法。然后在我的索引视图中,我从散列中获取数据,而不是从scoped_collection中获取数据。
不幸的是,我无法弄清楚如何在索引范围内提供实例变量。我通过将它放入params散列(在索引范围内可用)来解决这个问题,但最终会破坏过滤。
那么,有没有什么方法我没有看到范围内的变量来自scoped_collection或其他类似于before_filter的方法,这些方法可以在索引中使用?
示例代码:
ActiveAdmin.register ComplexResource do
actions :index
controller do
def scoped_collection
@complex_collection_relation = ComplexResource.where(crazy: :stuff)
# a bunch more lines of code to do avoid n+1's and put info into supporting data hash
@supporting_data_hash = {}
complex_collection_relation.each{|r| supporting_data_hash[r.id] = stuff }
# my hacky workaround because @supporting_data_hash isn't available below
params[:supporting_data_hash] = @supporting_data_hash
return @complex_collection_relation
end
end
filter :my_filter_that_gets_broken, as: :string
index do
column :name
column :complex_attribute_1 do |r|
params[:supporting_data_hash][r.id][:complex_attribute_1]
end
# how can I do something like this without using the params workaround
# column :complex_attribute_1 do |r|
# @supporting_data_hash[r.id][:complex_attribute_1]
# end
end
end
答案 0 :(得分:0)
答案 1 :(得分:0)
我知道这是一个老问题,但它是第一个在谷歌搜索时出现的问题。此外,我不是百分百肯定它适用于重复的问题所以我会在这里留下我的答案:
在为资源定义列时,可以作为帮助程序访问实例变量。 E.g:
ActiveAdmin.register Company do
controller do
before_action :load_data, only: :index
def load_data
@loaded_data = expensive_operation
end
end
index do
column 'Something' do |company|
loaded_data[company.id]
end
end
end
上找到了对它的引用