Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 25 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ json.array! @comments do |comment|
end
end

# => [ { "body": "great post...", "author": { "first_name": "Joe", "last_name": "Bloe" }} ]
# => [ { "body": "great post...", "author": { "first_name": "Joe", "last_name": "Blow" }} ]
```

## Array Attributes
Expand Down Expand Up @@ -209,6 +209,13 @@ the partial.
json.partial! 'comments/comments', comments: @message.comments
```

You can also render an object to a partial inline under a key.

```ruby
json.post @post, partial: 'posts/post', as: :post
# => { "post": { "title": "Hello World!", "author": { "name": "David" } } }
```

It's also possible to render collections of partials:

```ruby
Expand All @@ -219,9 +226,24 @@ json.partial! 'posts/post', collection: @posts, as: :post

# or
json.partial! partial: 'posts/post', collection: @posts, as: :post
```

# or
You can also render to a collection of partials inline under a key.

```ruby
json.comments @post.comments, partial: 'comments/comment', as: :comment
# => { "comments": [{ "content": "Hello everyone!" }, { "content": "To you my good sir!" }] }
```

You can also provide other locals to the partial you're rendering to.

```ruby
# Provide the `include_body` local to the partial when rendering a single object
json.post @post, partial: 'posts/post', as: :post, include_body: true

# Provide a local to the partial when rendering a collection.
# Each item in the collection will render with `include_author: true`.
json.comments @post.comments, partial: 'comments/comment', as: :comment, include_author: true
```

The `as: :some_symbol` is used with partials. It will take care of mapping the passed in object to a variable for the
Expand Down Expand Up @@ -321,7 +343,7 @@ This will include both records as part of the cache key and updating either of t
## Formatting Keys

Keys can be auto formatted using `key_format!`, this can be used to convert
keynames from the standard ruby_format to camelCase:
key names from the standard ruby_format to camelCase:

```ruby
json.key_format! camelize: :lower
Expand Down
10 changes: 3 additions & 7 deletions lib/jbuilder/jbuilder_template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -174,15 +174,11 @@ def _render_partial_with_options(options)
array!
end
else
_render_partial options
options[:locals][:json] = self
@context.render options
Comment thread
rafaelfranca marked this conversation as resolved.
end
end

def _render_partial(options)
options[:locals][:json] = self
@context.render options
end
Comment thread
rafaelfranca marked this conversation as resolved.

def _cache_fragment_for(key, options, &block)
key = _cache_key(key, options)
_read_fragment_cache(key, options) || _write_fragment_cache(key, options, &block)
Expand Down Expand Up @@ -241,7 +237,7 @@ def _set_inline_partial(name, object, options)
end
else
_scope do
options[:locals] = { options[:as] => object }
options[options[:as]] = object

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the crux of the fix.

_render_partial_with_options options
end
end
Expand Down
23 changes: 21 additions & 2 deletions test/jbuilder_template_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
class JbuilderTemplateTest < ActiveSupport::TestCase
POST_PARTIAL = <<-JBUILDER
json.extract! post, :id, :body
json.title post.title if local_assigns.fetch(:include_title, false)
json.author do
first_name, last_name = post.author_name.split(nil, 2)
json.first_name first_name
Expand All @@ -30,7 +31,7 @@ class JbuilderTemplateTest < ActiveSupport::TestCase
}

AUTHORS = [ "David Heinemeier Hansson", "Pavel Pravosud" ].cycle
POSTS = (1..10).collect { |i| Post.new(i, "Post ##{i}", AUTHORS.next) }
POSTS = (1..10).collect { |i| Post.new(i, "Title #{i}", "Post ##{i}", AUTHORS.next) }

setup { Rails.cache.clear }

Expand Down Expand Up @@ -136,6 +137,18 @@ class JbuilderTemplateTest < ActiveSupport::TestCase
assert_equal [], render('json.array! @posts, partial: "post", as: :post', posts: nil)
end

test "single partial under key" do
result = render('json.post @post, partial: "post", as: :post', post: POSTS.first)
assert_equal "Post #1", result["post"]["body"]
assert_equal "Heinemeier Hansson", result["post"]["author"]["last_name"]
assert_equal "David", result["post"]["author"]["first_name"]
end

test 'single partial under key with local' do
result = render('json.post @post, partial: "post", as: :post, include_title: true', post: POSTS.first)
assert_equal "Title 1", result["post"]["title"]
end

test "array of partials under key" do
result = render('json.posts @posts, partial: "post", as: :post', posts: POSTS)
assert_equal 10, result["posts"].count
Expand All @@ -144,13 +157,19 @@ class JbuilderTemplateTest < ActiveSupport::TestCase
assert_equal "Pavel", result["posts"][5]["author"]["first_name"]
end

test "array of partials under key with local" do
result = render('json.posts @posts, partial: "post", as: :post, include_title: true', posts: POSTS)
assert_equal "Title 1", result["posts"][0]["title"]
assert_equal "Title 2", result["posts"][1]["title"]
end

test "empty array of partials under key from nil collection" do
Jbuilder::CollectionRenderer.expects(:new).never
result = render('json.posts @posts, partial: "post", as: :post', posts: nil)
assert_equal [], result["posts"]
end

test "empty array of partials under key from an empy collection" do
test "empty array of partials under key from an empty collection" do
Jbuilder::CollectionRenderer.expects(:new).never
result = render('json.posts @posts, partial: "post", as: :post', posts: [])
assert_equal [], result["posts"]
Expand Down
2 changes: 1 addition & 1 deletion test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class << Rails

Jbuilder::CollectionRenderer.collection_cache = Rails.cache

class Post < Struct.new(:id, :body, :author_name)
class Post < Struct.new(:id, :title, :body, :author_name)
def cache_key
"post-#{id}"
end
Expand Down
Loading