Skip to content

ActionView::DependencyTracker doesn't track jbuilder templates #126

Closed
@kipcole9

Description

@kipcole9

Rails 4 doesn't dependency check jbuilder templates. This code (use as an initialiser, and is a minor edit of the supplied ERB tracker) adds a dependency tracker for jbuilder files to aid in russian doll caching strategies. Expect this will only work in Rails 4 (tested on Beta 1).

module ActionView
  class JBuilderTracker
    # Matches:
    #   json.partial! 'application/status'
    #   json.partial! @topic
    #   json.partial! topics
    #   json.partial! message.topics
    RENDER_DEPENDENCY = /
      partial!\s*                   # partial! call, followed by optional whitespace
      ([@a-z"'][@a-z_\/\."']+)      # the template name itself -- 1st capture
    /x

    def self.call(name, template)
      new(name, template).dependencies
    end

    def initialize(name, template)
      @name, @template = name, template
    end

    def dependencies
      Rails.logger.debug "Template Dependencies for #{name}: #{render_dependencies} + #{explicit_dependencies}"
      render_dependencies + explicit_dependencies
    end

  private
    attr_reader :name, :template

    def source
      template.source
    end

    def directory
      name.split("/")[0..-2].join("/")
    end

    def render_dependencies
      source.scan(RENDER_DEPENDENCY).
        collect(&:first).uniq.

        # partial! @topic           => "topics/topic"
        # partial! topics           => "topics/topic"
        # partial! message.topics   => "topics/topic"
        collect { |name| name.sub(/\A@?([a-z]+\.)*([a-z_]+)\z/) { "#{$2.pluralize}/#{$2.singularize}" } }.

        # partial! "headline"       => "message/headline"
        collect { |name| name.include?("/") ? name : "#{directory}/#{name}" }.

        # replace quotes from string renders
        collect { |name| name.gsub(/["']/, "") }
    end

    def explicit_dependencies
      source.scan(ActionView::DependencyTracker::ERBTracker::EXPLICIT_DEPENDENCY).flatten.uniq
    end
  end
end

ActiveSupport.on_load(:action_view) do
  ActiveSupport.on_load(:after_initialize) do
    require 'action_view/dependency_tracker'
    ActionView::DependencyTracker.register_tracker :jbuilder, ActionView::JBuilderTracker
  end
end

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions