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
Integrating collection renderer from ActionView (#43)
# Goal
We should be able to effectively render collection of data and be able to cache it.
## Problem statement
Previously, we have used following code to render collection:
```ruby
pb.cache!(@account.offers_cache_key, expires_in: 12.hours) do
pb.featured_offers @featured_offers, partial: "offer", as: :offer
pb.normal_offers @normal_offers, partial: "offer", as: :offer
end
```
But we need to introduce fragment caching to offers, since list cache has high miss rate. This is how implementing fragment caching in pbbuilder should look like:
```ruby
pb.cache!(@account.offers_cache_key, expires_in: 12.hours) do
pb.featured_offers partial: "offer", as: offer, collection: @featured_offers, cached: true
pb.normal_offers partial: "offer", as: :offer, collection: @normal_offers, cached: true
end
```
This syntax is heavily inspired by jbuilder. Here is list of examples from that gem that uses cached: and collection: attributes.
```ruby
json.partial! partial: 'posts/post', collection: @posts, as: :post
```
```ruby
json.partial! 'posts/post', collection: @posts, as: :post
```
```ruby
json.partial! "post", collection: @posts, cached: true, as: :post
```
```ruby
json.array! @posts, partial: "post", as: :post, cached: true
```
```ruby
json.array! @posts, partial: "posts/post", as: :post, cached: true
```
```ruby
json.comments @post.comments, partial: "comments/comment", as: :comment, cached:true
```
## Proposed solution
In this PR, we're implementing more effective rendering of collection with a help of `ActiveView::CollectionRenderer`. Support for caching of partial is currently not in the scope, but this will help implement caching and caching digest later.
Following syntax should be supported:
```ruby
pb.friends partial: "racers/racer", as: :racer, collection: @Racers
```
```ruby
pb.friends "racers/racer", as: :racer, collection: @Racers
```
Previous syntax works as it used to before. These will remain unchanged and will not use collection renderer (at least for now)
```ruby
pb.partial! @racer, racer: Racer.new(123, "Chris Harris", friends)
```
```ruby
pb.friends @friends, partial: "racers/racer", as: :racer
```
## TODO
- [x] Add documentation for this change
- [ ] Check performance difference between Collection Renderer and our approach. (without cache for now)
- [x] It's using PartialRenderer with rails 7 now - this seems like a bug, it should use CollectionRenderer.
## Prior work
Some inspiration for this PR could be found here:
* rails/jbuilder#501
* https://github.com/rails/rails/blob/main/actionview/lib/action_view/renderer/partial_renderer/collection_caching.rb#L20
* https://github.com/rails/rails/tree/main/actionview collection_renderer
* https://github.com/rails/rails/blob/main/actionview/lib/action_view/renderer/partial_renderer/collection_caching.rb#L20
Copy file name to clipboardexpand all lines: README.md
+30-5
Original file line number
Diff line number
Diff line change
@@ -1,21 +1,26 @@
1
1
# Pbbuilder
2
2
PBBuilder generates [Protobuf](https://developers.google.com/protocol-buffers) Messages with a simple DSL similar to [JBuilder](https://rubygems.org/gems/jbuilder) gem.
3
3
4
-
## Compatibility
5
-
We don't aim to have 100% compatibility with jbuilder gem, but we closely follow jbuilder's API design.
4
+
5
+
At least Rails 6.1 is required.
6
+
7
+
## Compatibility with jBuilder
8
+
We don't aim to have 100% compitability and coverage with jbuilder gem, but we closely follow jbuilder's API design to maintain familiarity.
6
9
7
10
|| Jbuilder | Pbbuilder |
8
11
|---|---|---|
9
12
| set! | ✅ | ✅ |
10
13
| cache! | ✅ | ✅ |
11
14
| cache_if! | ✅ | ✅ |
12
15
| cache_root! | ✅||
16
+
| collection cache | ✅||
13
17
| extract! | ✅ | ✅ |
14
18
| merge! | ✅ | ✅ |
15
-
| deep_format_keys! | ✅ ||
16
19
| child! | ✅ ||
17
20
| array! | ✅ ||
18
-
| ignore_nil! | ✅ ||
21
+
| .call | ✅ ||
22
+
23
+
Due to protobuf message implementation, there is absolutely no need to implement support for `deep_format_keys!`, `key_format!`, `key_format`, `deep_format_keys`, `ignore_nil!`, `ignore_nil!`, `nil`. So those would never be added.
19
24
20
25
## Usage
21
26
The main difference is that it can use introspection to figure out what kind of protobuf message it needs to create.
@@ -76,8 +81,26 @@ Here is way to use partials with collection while passing a variable to it
0 commit comments