Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 8542

Show
Ignore:
Timestamp:
01/03/08 15:35:10 (4 months ago)
Author:
david
Message:

Made fragment caching in views work for rjs and builder as well (closes #6642) [zsombor]

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/actionpack/CHANGELOG

    r8541 r8542  
    11*SVN* 
     2 
     3* Made fragment caching in views work for rjs and builder as well #6642 [zsombor] 
    24 
    35* Fixed rendering of partials with layout when done from site layout #9209 [antramm] 
  • trunk/actionpack/lib/action_controller/caching.rb

    r8365 r8542  
    372372      end 
    373373 
    374       # Called by CacheHelper#cache 
    375       def cache_erb_fragment(block, name = {}, options = nil) 
     374      def fragment_for(block, name = {}, options = nil) #:nodoc: 
    376375        unless perform_caching then block.call; return end 
    377376 
    378         buffer = eval(ActionView::Base.erb_variable, block.binding) 
     377        buffer = yield 
    379378 
    380379        if cache = read_fragment(name, options) 
     
    386385        end 
    387386      end 
     387 
     388      # Called by CacheHelper#cache 
     389      def cache_rxml_fragment(block, name = {}, options = nil) #:nodoc: 
     390        fragment_for(block, name, options) do 
     391          eval('xml.target!', block.binding) 
     392        end 
     393      end 
     394       
     395      # Called by CacheHelper#cache 
     396      def cache_rjs_fragment(block, name = {}, options = nil) #:nodoc: 
     397        fragment_for(block, name, options) do 
     398          begin 
     399            debug_mode, ActionView::Base.debug_rjs = ActionView::Base.debug_rjs, false 
     400            eval('page.to_s', block.binding) 
     401          ensure 
     402            ActionView::Base.debug_rjs = debug_mode 
     403          end 
     404        end 
     405      end 
     406       
     407      # Called by CacheHelper#cache 
     408      def cache_erb_fragment(block, name = {}, options = nil) #:nodoc: 
     409        fragment_for(block, name, options) do 
     410          eval(ActionView::Base.erb_variable, block.binding) 
     411        end 
     412      end 
     413 
    388414 
    389415      # Writes <tt>content</tt> to the location signified by <tt>name</tt> (see <tt>expire_fragment</tt> for acceptable formats) 
  • trunk/actionpack/lib/action_view/helpers/cache_helper.rb

    r7106 r8542  
    3333      #    <% end %> 
    3434      def cache(name = {}, &block) 
    35         @controller.cache_erb_fragment(block, name) 
     35        template_extension = first_render[/\.(\w+)$/, 1].to_sym 
     36        case template_extension 
     37        when :erb, :rhtml 
     38          @controller.cache_erb_fragment(block, name) 
     39        when :rjs 
     40          @controller.cache_rjs_fragment(block, name) 
     41        when :builder, :rxml 
     42          @controller.cache_rxml_fragment(block, name) 
     43        else 
     44          # do a last ditch effort for those brave souls using 
     45          # different template engines. This should give plugin 
     46          # writters a simple hook. 
     47          raise "fragment caching not supported for #{template_extension} files." unless @controller.respond_to?("cache_#{template_extension}_fragment") 
     48          @controller.send "cache_#{template_extension}_fragment", block, name 
     49        end 
    3650      end 
    3751    end 
  • trunk/actionpack/test/controller/caching_test.rb

    r8226 r8542  
    2626    head :not_found 
    2727  end 
    28    
     28 
    2929  def custom_path 
    3030    render :text => "Super soaker" 
    3131    cache_page("Super soaker", "/index.html") 
    3232  end 
    33    
     33 
    3434  def expire_custom_path 
    3535    expire_page("/index.html") 
    3636    head :ok 
    3737  end 
    38    
     38 
    3939  def trailing_slash 
    4040    render :text => "Sneak attack" 
     
    9696    assert !File.exist?("#{FILE_STORE_PATH}/index.html") 
    9797  end 
    98    
     98 
    9999  def test_should_cache_without_trailing_slash_on_url 
    100100    @controller.class.cache_page 'cached content', '/page_caching_test/trailing_slash' 
     
    216216    assert_equal cached_time, @response.body 
    217217  end 
    218    
     218 
    219219  def test_action_cache_with_custom_cache_path 
    220220    get :show 
     
    263263    get :index 
    264264    jamis_cache = content_to_cache 
    265      
    266     reset! 
    267      
     265 
     266    reset! 
     267 
    268268    @request.host = 'david.hostname.com' 
    269269    get :index 
     
    309309    assert_equal 'example.org/posts/index.xml', path_object.path 
    310310  end 
    311    
     311 
    312312  def test_correct_content_type_is_returned_for_cache_hit 
    313313    # run it twice to cache it the first time 
     
    342342      @request.host = 'hostname.com' 
    343343    end 
    344      
     344 
    345345    def assert_cache_exists(path) 
    346346      full_path = File.join(FILE_STORE_PATH, path + '.cache') 
     
    348348    end 
    349349end 
     350 
     351class FragmentCachingTestController < ActionController::Base 
     352  def some_action; end; 
     353end 
     354 
     355class FragmentCachingTest < Test::Unit::TestCase 
     356  def setup 
     357    ActionController::Base.perform_caching = true 
     358    @store = ActionController::Caching::Fragments::UnthreadedMemoryStore.new 
     359    ActionController::Base.fragment_cache_store = @store 
     360    @controller = FragmentCachingTestController.new 
     361    @params = {:controller => 'posts', :action => 'index'} 
     362    @request = ActionController::TestRequest.new 
     363    @response = ActionController::TestResponse.new 
     364    @controller.params = @params 
     365    @controller.request = @request 
     366    @controller.response = @response 
     367    @controller.send(:initialize_current_url) 
     368  end 
     369 
     370  def test_fragement_cache_key 
     371    assert_equal 'what a key', @controller.fragment_cache_key('what a key') 
     372    assert_equal( "test.host/fragment_caching_test/some_action", 
     373                  @controller.fragment_cache_key(:controller => 'fragment_caching_test',:action => 'some_action')) 
     374  end 
     375 
     376  def test_read_fragment__with_caching_enabled 
     377    @store.write('name', 'value') 
     378    assert_equal 'value', @controller.read_fragment('name') 
     379  end 
     380 
     381  def test_read_fragment__with_caching_disabled 
     382    ActionController::Base.perform_caching = false 
     383    @store.write('name', 'value') 
     384    assert_nil @controller.read_fragment('name') 
     385  end 
     386 
     387  def test_write_fragment__with_caching_enabled 
     388    assert_nil @store.read('name') 
     389    assert_equal 'value', @controller.write_fragment('name', 'value') 
     390    assert_equal 'value', @store.read('name') 
     391  end 
     392 
     393  def test_write_fragment__with_caching_disabled 
     394    assert_nil @store.read('name') 
     395    ActionController::Base.perform_caching = false 
     396    assert_equal nil, @controller.write_fragment('name', 'value') 
     397    assert_nil @store.read('name') 
     398  end 
     399 
     400  def test_expire_fragment__with_simple_key 
     401    @store.write('name', 'value') 
     402    @controller.expire_fragment 'name' 
     403    assert_nil @store.read('name') 
     404  end 
     405 
     406  def test_expire_fragment__with__regexp 
     407    @store.write('name', 'value') 
     408    @store.write('another_name', 'another_value') 
     409    @store.write('primalgrasp', 'will not expire ;-)') 
     410 
     411    @controller.expire_fragment /name/ 
     412 
     413    assert_nil @store.read('name') 
     414    assert_nil @store.read('another_name') 
     415    assert_equal 'will not expire ;-)', @store.read('primalgrasp') 
     416  end 
     417 
     418  def test_fragment_for__with_disabled_caching 
     419    ActionController::Base.perform_caching = false 
     420 
     421    @store.write('expensive', 'fragment content') 
     422    fragment_computed = false 
     423 
     424    buffer = 'generated till now -> ' 
     425    @controller.fragment_for(Proc.new { fragment_computed = true }, 'expensive') { buffer } 
     426 
     427    assert fragment_computed 
     428    assert_equal 'generated till now -> ', buffer 
     429  end 
     430 
     431 
     432  def test_fragment_for 
     433    @store.write('expensive', 'fragment content') 
     434    fragment_computed = false 
     435 
     436    buffer = 'generated till now -> ' 
     437    @controller.fragment_for(Proc.new { fragment_computed = true }, 'expensive') { buffer} 
     438 
     439    assert !fragment_computed 
     440    assert_equal 'generated till now -> fragment content', buffer 
     441  end 
     442 
     443  def test_cache_erb_fragment 
     444    @store.write('expensive', 'fragment content') 
     445    _erbout = 'generated till now -> ' 
     446 
     447    assert_equal( 'generated till now -> fragment content', 
     448                  @controller.cache_erb_fragment(Proc.new{ }, 'expensive')) 
     449  end 
     450 
     451  def test_cache_rxml_fragment 
     452    @store.write('expensive', 'fragment content') 
     453    xml = 'generated till now -> ' 
     454    class << xml; def target!; to_s; end; end 
     455 
     456    assert_equal( 'generated till now -> fragment content', 
     457                  @controller.cache_rxml_fragment(Proc.new{ }, 'expensive')) 
     458  end 
     459 
     460  def test_cache_rjs_fragment 
     461    @store.write('expensive', 'fragment content') 
     462    page = 'generated till now -> ' 
     463 
     464    assert_equal( 'generated till now -> fragment content', 
     465                  @controller.cache_rjs_fragment(Proc.new{ }, 'expensive')) 
     466  end 
     467 
     468  def test_cache_rjs_fragment_debug_mode_does_not_interfere 
     469    @store.write('expensive', 'fragment content') 
     470    page = 'generated till now -> ' 
     471 
     472    begin 
     473      debug_mode, ActionView::Base.debug_rjs = ActionView::Base.debug_rjs, true 
     474      assert_equal( 'generated till now -> fragment content', 
     475                    @controller.cache_rjs_fragment(Proc.new{ }, 'expensive')) 
     476      assert ActionView::Base.debug_rjs 
     477    ensure 
     478      ActionView::Base.debug_rjs = debug_mode 
     479    end 
     480  end 
     481end