You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 06e86fc
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: docs/CHANGELOG.md
+18Lines changed: 18 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -14,6 +14,24 @@ nav_order: 6
14
14
15
15
*Erik Axel Nielsen*
16
16
17
+
* Give `<% cache %>` blocks inside a component's own template a digest, for components that `include ViewComponent::ExperimentallyCacheable`.
18
+
19
+
Rails digests the virtual path of whichever template is rendering. Inside a component that path resolves to no template, because component templates aren't in the view paths, so the Digestor returned an empty digest and the fragment was never invalidated. The only signal was a `Couldn't find template for digesting` line in the log. 4.15.0 fixed the case where the `cache` block wraps the component in a view. This fixes the case where the block sits in the component's template.
20
+
21
+
*Erik Axel Nielsen*
22
+
23
+
* Fix line numbers and, under coverage, missing output for ERB templates that Rails doesn't annotate.
24
+
25
+
On Rails 8.1+, ViewComponent compensated for the newline Rails adds to compiled ERB output ([rails/rails#53731](https://github.com/rails/rails/pull/53731)) for every ERB template, whether from a file or from `erb_template`. That newline lives inside the `<!-- BEGIN ... -->` annotation, which Rails only emits when `annotate_rendered_view_with_filenames` is enabled *and* the template's format is HTML. Compensating unconditionally shifted backtraces for non-HTML templates (`.text.erb`, `.css.erb`) and for every ERB template when annotations are disabled, such as in production, by one line. When coverage was running, the same mismatch made the annotation-stripping workaround remove real template source, so non-HTML templates rendered empty.
26
+
27
+
Inline templates now decide the compensation when they compile rather than when the component class is defined, matching file templates.
28
+
29
+
*Ryutaro Mizokami*
30
+
31
+
* Reduce per-render allocations. Inline renders drop 2 to 3 allocations and collection renders drop 4 to 8 depending on Rails/Ruby version by caching the instrumentation-enabled flag at the module level, memoizing the empty-details `Requested` per `LookupContext`, hoisting per-item metadata lookups out of the collection render loop, and dropping a few gratuitous `**` splats on the `Collection` API boundary.
32
+
33
+
*Joel Hawksley*
34
+
17
35
## 4.15.0
18
36
19
37
* Add experimental caching support, opt-in per component via `include ViewComponent::ExperimentallyCacheable`.
Copy file name to clipboardExpand all lines: docs/best_practices.md
-2Lines changed: 0 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -42,8 +42,6 @@ For example, `User::AvatarComponent` accepts a `User` ActiveRecord object and re
42
42
43
43
### Extract general-purpose ViewComponents
44
44
45
-
"Good frameworks are extracted, not invented" - [DHH](https://dhh.dk/arc/000416.html)
46
-
47
45
Just as ViewComponent itself was extracted from GitHub.com, general-purpose components are best extracted once they've proven helpful across more than one area:
Copy file name to clipboardExpand all lines: docs/guide/caching.md
+15Lines changed: 15 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -42,6 +42,21 @@ end
42
42
43
43
That's all that's needed for the `<% cache %>` block above to work. The component is registered with Rails' digest tree, and the fragment is invalidated when the component's template, Ruby class, sidecar files, superclasses, child components, or rendered partials change, including components and partials rendered from an inline template or a `#call` method.
44
44
45
+
## Caching inside a component template
46
+
47
+
A `<% cache %>` block written inside a component's own template has the same problem, for the same reason: Rails digests the template that's rendering, and a component's template isn't in the view paths, so there's nothing to digest.
48
+
49
+
```erb
50
+
<%# app/components/post_component.html.erb %>
51
+
<% cache @post do %>
52
+
<%= render CommentComponent.new(post: @post) %>
53
+
<% end %>
54
+
```
55
+
56
+
Including the module fixes this too. The component's own digest is substituted for the empty one Rails computes, so the fragment is invalidated by the same set of changes listed above. A component that hasn't opted in gets no digest at all, and the fragment is never invalidated.
57
+
58
+
`cache` blocks in partials the component renders are unaffected: those templates resolve through the view paths like any other, so Rails digests them itself.
59
+
45
60
## Self-caching
46
61
47
62
To have a component cache its own output without needing a `cache` block, use `cache_on` to declare methods used for the component's cache key.
0 commit comments