|
2 | 2 |
|
3 | 3 | require "active_record_unit"
|
4 | 4 |
|
| 5 | +class MultifetchController < ActionController::Base |
| 6 | + ROUTES = test_routes do |
| 7 | + get :cached_true, to: "multifetch#cached_true" |
| 8 | + get :cached_proc, to: "multifetch#cached_proc" |
| 9 | + end |
| 10 | + |
| 11 | + def cached_true |
| 12 | + load_all_topics |
| 13 | + render partial: "test/multifetch", collection: @topics, as: :topic, cached: true |
| 14 | + end |
| 15 | + |
| 16 | + def cached_proc |
| 17 | + load_all_topics |
| 18 | + render partial: "test/multifetch", collection: @topics, as: :topic, cached: proc { |topic| [topic] } |
| 19 | + end |
| 20 | + |
| 21 | + private |
| 22 | + def load_all_topics |
| 23 | + @topics = Topic.preload(:replies) |
| 24 | + end |
| 25 | +end |
| 26 | + |
5 | 27 | class MultifetchCacheTest < ActiveRecordTestCase
|
| 28 | + tests MultifetchController |
6 | 29 | fixtures :topics, :replies
|
7 | 30 |
|
8 |
| - def setup |
9 |
| - view_paths = ActionController::Base.view_paths |
10 |
| - view_paths.each(&:clear_cache) |
| 31 | + setup do |
| 32 | + Topic.update_all(updated_at: Time.now) |
| 33 | + end |
| 34 | + |
| 35 | + def test_only_preloading_for_records_that_miss_the_cache |
| 36 | + Topic.update_all(title: "title") |
11 | 37 |
|
12 |
| - @view = Class.new(ActionView::Base.with_empty_template_cache) do |
13 |
| - def view_cache_dependencies |
14 |
| - [] |
15 |
| - end |
| 38 | + # The first request will not have anything cached, so we need to render all the records |
| 39 | + first_req = capture_sql do |
| 40 | + get :cached_true |
| 41 | + end |
| 42 | + assert_equal 3, @response.body.scan(/title/).length |
| 43 | + assert_equal 2, first_req.length |
| 44 | + assert_includes first_req.last, %(WHERE "replies"."topic_id" IN (?, ?, ?)) |
16 | 45 |
|
17 |
| - def combined_fragment_cache_key(key) |
18 |
| - [ :views, key ] |
19 |
| - end |
20 |
| - end.with_view_paths(view_paths, {}) |
| 46 | + Topic.first.update(updated_at: 1.hour.ago) # reset the cache key for this object |
21 | 47 |
|
22 |
| - controller = ActionController::Base.new |
23 |
| - controller.perform_caching = true |
24 |
| - @view.controller = controller |
| 48 | + # Now we only load the one record that we don't have a cached view for. |
| 49 | + second_req = capture_sql do |
| 50 | + get :cached_true |
| 51 | + end |
| 52 | + assert_equal 3, @response.body.scan(/title/).length |
| 53 | + assert_equal 2, second_req.length |
| 54 | + assert_equal first_req.first, second_req.first |
| 55 | + assert_includes second_req.last, %(WHERE "replies"."topic_id" = ?) |
25 | 56 | end
|
26 | 57 |
|
27 |
| - def test_only_preloading_for_records_that_miss_the_cache |
28 |
| - @view.render partial: "test/partial", collection: [topics(:rails)], cached: true |
| 58 | + def test_preloads_all_records_if_using_cached_proc |
| 59 | + Topic.update_all(title: "title") |
29 | 60 |
|
30 |
| - @topics = Topic.preload(:replies) |
| 61 | + # The first request will not have anything cached, so we need to render all the records |
| 62 | + first_req = capture_sql do |
| 63 | + get :cached_proc |
| 64 | + end |
| 65 | + assert_equal 3, @response.body.scan(/title/).length |
| 66 | + assert_equal 2, first_req.length |
| 67 | + assert_includes first_req.last, %(WHERE "replies"."topic_id" IN (?, ?, ?)) |
31 | 68 |
|
32 |
| - @view.render partial: "test/partial", collection: @topics, cached: true |
| 69 | + Topic.first.update(updated_at: 1.hour.ago) # reset the cache key for this object |
33 | 70 |
|
34 |
| - assert_not @topics.detect { |topic| topic.id == topics(:rails).id }.replies.loaded? |
35 |
| - assert @topics.detect { |topic| topic.id != topics(:rails).id }.replies.loaded? |
| 71 | + # Since we are using a proc, we will preload the entire association. |
| 72 | + second_req = capture_sql do |
| 73 | + get :cached_proc |
| 74 | + end |
| 75 | + assert_equal 3, @response.body.scan(/title/).length |
| 76 | + assert_equal 2, second_req.length |
| 77 | + assert_equal first_req.first, second_req.first |
| 78 | + assert_includes second_req.last, %(WHERE "replies"."topic_id" IN (?, ?, ?)) |
36 | 79 | end
|
37 | 80 | end
|
0 commit comments