Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

avoid N+1 queries for attached images #3282

Closed
loicginoux opened this issue Jun 4, 2020 · 0 comments
Closed

avoid N+1 queries for attached images #3282

loicginoux opened this issue Jun 4, 2020 · 0 comments
Milestone

Comments

@loicginoux
Copy link
Contributor

I customized a list view displaying multiple informations and realised there are many N+1 requests when showing the list views.
I managed to make them disappear for associations with an attribute eager_load (which is by the way not really documented, I had to dig in the code and several other issues mentionning it).

So let's say with have posts which have many comments we can do the following for displaying the posts list:

list do
  fields :comments do
    formatted_value do
      bindings[:view].render partial: 'rails_admin/posts/comments_preview', locals: { ride: bindings[:object] }
    end
    eager_load true
  end
end

The problem now I am facing is that if a post has photos and I want to display them in the list view, there is no way, currently to not do N+1 queries for them.

What would be good is something a bit similar as for associations:

list do
  fields :photos do
    eager_load true
  end
end

then when loading the posts collection it would basically do something like this, supposing we use active storage:

Posts.with_attached_photos.all

At the moment the only way I managed to fix the N+1 query is overwritting the get_collection method for this model in particular adding the following in config/initializers/rails_admin.rb:

require 'rails_admin/main_controller'
module RailsAdmin
  class MainController < RailsAdmin::ApplicationController
    def get_collection(model_config, scope, pagination)
      associations = model_config.list.fields.select { |f| f.try(:eager_load?) }.collect { |f| f.association.name }
      options = {}
      options = options.merge(page: (params[Kaminari.config.param_name] || 1).to_i, per: (params[:per] || model_config.list.items_per_page)) if pagination
      options = options.merge(include: associations) unless associations.blank?
      options = options.merge(get_sort_hash(model_config))
      options = options.merge(query: params[:query]) if params[:query].present?
      options = options.merge(filters: params[:f]) if params[:f].present?
      options = options.merge(bulk_ids: params[:bulk_ids]) if params[:bulk_ids]
      if model_config.abstract_model.to_s == "Ride"
        model_config.abstract_model.all(options, scope.with_attached_photos)
      else
        model_config.abstract_model.all(options, scope)
      end
    end
  end
end
@mshibuya mshibuya added this to the 3.0.0 milestone Aug 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants