rabl
rabl copied to clipboard
Eager loading not working when calling Rabl::Renderer directly
Rails 4, RABL 0.9.4pre1 and 0.9.3, Mongoid 4.0.0.beta1
In one controller I have an action like
def index
@bookmarks = current_user.bookmarks.includes(:channels, :user)
end
Which renders the rabl template that includes references to model's relations hitting the db only a couple of times.
But when I try
@bookmarks = current_user.bookmarks.includes(:channels, :user)
Rabl::Renderer.json(@bookmarks, 'api/bookmarks/index')
This gets the N+1 query problem. The template is the same.
I tried:
- to pass in the controller scope
Rabl::Renderer.json(@bookmarks, 'api/bookmarks/index', scope: self)
- to put .includes inside the call
Rabl::Renderer.json(@bookmarks.includes(:channels, :user), 'api/bookmarks/index')
- Using different styles of initializing Rabl::Renderer
This is the code that works correctly, as I understand:
module ActionView
module Template::Handlers
class Rabl
class_attribute :default_format
self.default_format = Mime::JSON
def self.call(template)
source = template.source
%{ ::Rabl::Engine.new(#{source.inspect}).
render(self, assigns.merge(local_assigns)) }
end # call
end # rabl class
end # handlers
Any ideas of why it may be happening?
+1, running into this issue right now myself. @funtusov have you managed to find any solutions?
+1, been unable to eager load anything using Rabl
+1 Can't use Rabl in production with this bug.
If anyone can track down the culprit and submit a pull request, I'd love to merge. Are you all using Mongoid when you see this issue?
@finch1642 and @daveroberts; are you seeing the same issue @funtusov is, where eager loading works with regular controller/action/view, just not when using Rabl::Renderer
directly, or are you seeing eager loading never work at all?
@DouweM I am seeing eager loading never work at all
What versions of Rabl and ActiveRecord/Mongoid are you on and what do your controller and views look like?
ActiveRecord 4.1.7 Rabl 0.11.4 Using multiple SQL databases and experiencing the same issue
My controllers/views vary in complexity, but even the most simple scenario doesn't utilize eager loading.
Controller:
@posts = Post.all.includes(:comments)
render "posts/index.json.rabl"
Views:
posts/index.json.rabl
collection @posts
attributes :id
child :comments do
extends "comments/index"
end
comments/index.json.rabl
collection @comments
attributes :id,:text
Could you try again with Rabl master and let me know how that goes? I have no idea if the recent changes affect it in any way, but that way we're at least on the same page.
Still not working, at least with mongoid.
+1 it does not work with mongoid.
You can nevertheless use:
@posts = Post.all.includes(:comments).cache
respond_with @posts
In that case the database won't be hit again during the view rendering
+1 any solution/workaround?
+1
+1
+1
+1
+1