nesquena / rabl

General ruby templating with json, bson, xml, plist and msgpack support
http://blog.codepath.com/2011/06/27/building-a-platform-api-on-rails/
MIT License
3.64k stars 334 forks source link

Cache digesting errors when using "extends" #700

Closed zhengpd closed 1 year ago

zhengpd commented 7 years ago

I saw some digesting errors when using "extends" in the rabl template:

'foo/bar' file doesn't exist, so no dependencies
Couldn't find template for digesting: foo/bar

The template is like:

cache [I18n.locale, root_object]
child :something do
  extends 'foo/bar' # full path is foo/bar.rabl, not a partial like foo/_bar.rabl
end

After some research I believe this is caused by how ActionView::Digestor build the dependency tree:

# https://github.com/rails/rails/blob/a8ebd48559bea8893aa299f9e27758da0807ef24/actionview/lib/action_view/digestor.rb#L61
def tree(name, finder, partial = false, seen = {})
  ...
  deps = DependencyTracker.find_dependencies(name, template, finder.view_paths)
  deps.uniq { |n| n.gsub(%r|/_|, "/") }.each do |dep_file|
       node.children << tree(dep_file, finder, true, seen)
   end
  ...
end

Look the node.children << tree(dep_file, finder, true, seen) here. It treats every dependency it found in template as partial, so it tries to find the partial file as foo/_bar in my example, not foo/bar as expected. I override the tree method as following for quick fix:

deps.uniq { |n| n.gsub(%r|/_|, "/") }.each do |dep_file|
  # all rabl files under foo/ are treated as non-partials
  partial = dep_file.exclude?('foo/')
  node.children << tree(dep_file, finder, partial, seen)
end

However I wonder there's more elegant way other than this to avoid digesting errors.

jvalentino90 commented 5 years ago

hello @ericbeansmile, I've run into the same problem. Where and how have you overriden the tree method? thanks!

zhengpd commented 5 years ago

@jvalentino90 You can create config/initializers/action_view.rb with following content:

module ActionView
  class Digestor
    def self.tree(name, finder, partial = false, seen = {})
      # copy original method body from https://github.com/rails/rails/blob/aa1ba9cb244b1e03d36aaa941ae4e91c6713b77e/actionview/lib/action_view/digestor.rb#L47
    end
  end
end

Inside the method body just make change like my comment above.

zhengpd commented 1 year ago

Closing stale issue.