jbuilder-jpartial 1.0.2 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +17 -14
- data/lib/generators/jpartial_generator.rb +16 -0
- data/lib/generators/templates/jpartial.rb.erb +19 -0
- data/lib/jbuilder/jpartial.rb +42 -28
- data/lib/jbuilder/jpartial/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 484a3494bea19dd423cd1bfec8942c5e47475541
|
4
|
+
data.tar.gz: 1dc470a7f1a92377a054fe33031757b8398f4e08
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0611e2298872183b2458663ece24039a8b3b205944ddd7dfa586ebfb38d562ece8fed535038d81a36dffa1f4a18d115231348de395aa7fbac542bfb227d4c3d
|
7
|
+
data.tar.gz: 792df2214b9d1869cb3d55b97da7a6c4b0506511d1a1ffbf864f32c7f699535a0391603e345f330932b6cf462d0083e80fecdb35b897cc5efe51bce1e8d8901a
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
1.1
|
4
|
+
-----
|
5
|
+
* Do less monkey patching on the original Jbuilder class. Only add the partial methods defined by the user, otherwise leave Jbuilder alone and leave the rest to a proxy class.
|
6
|
+
* Make sure all view helper methods are available in partials, not just route helpers.
|
7
|
+
* Add Rails generator for initializer file.
|
data/README.md
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# Jbuilder::Jpartial
|
2
2
|
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/jbuilder-jpartial.svg)](https://badge.fury.io/rb/jbuilder-jpartial)
|
4
|
+
[![Build Status](https://travis-ci.org/msimonborg/jbuilder-jpartial.svg?branch=master)](https://travis-ci.org/msimonborg/jbuilder-jpartial)
|
5
|
+
|
3
6
|
A lightweight library that provides a simple DSL for faster partial rendering with Jbuilder.
|
4
7
|
|
5
8
|
## Installation
|
@@ -17,7 +20,7 @@ And then execute:
|
|
17
20
|
Or install it yourself as:
|
18
21
|
|
19
22
|
$ gem install jbuilder-jpartial
|
20
|
-
|
23
|
+
|
21
24
|
require 'jbuilder/jpartial'
|
22
25
|
|
23
26
|
## Usage
|
@@ -72,13 +75,18 @@ end
|
|
72
75
|
#### Why?
|
73
76
|
When partials are used with `Jbuilder` render times and memory usage can skyrocket quickly with the number of records, i.e. the number of partials rendered.
|
74
77
|
|
75
|
-
Using a simple DSL, `Jbuilder::Jpartial` lets you define your partials in a familiar way while dramatically reducing overhead.
|
78
|
+
Using a simple DSL, `Jbuilder::Jpartial` lets you define your partials in a familiar way while dramatically reducing overhead.
|
76
79
|
|
77
80
|
The result is faster rendering and lower memory usage, while still being able to leverage the advantages of Jbuilder. In the above example, if we had used standard Jbuilder partials those templates would have to be rendered once for each `post` and/or `comment`. If you have 50 posts, each with 50 comments, that's 2,550 templates rendered! Using `Jbuilder::Jpartial`, the partial files are each only called when the partial is initialized. After that, all of the partial rendering is taken care of in the abstract from the original file. In our example, we hit `json.partial! 'post'` once and `json.partial! 'comments/comment'` only once for each `post`, cutting 2,550 template renders down to 51.
|
78
81
|
|
79
82
|
Alternatively you can define all partials in one initializer file and call them wherever you need them: from within other partial definitions or anywhere you use `Jbuilder` in your views. The big advantage here is since they're initialized at start up, you don't need to call any additional view templates to render the partials. Using the same example as above:
|
80
83
|
|
81
|
-
####
|
84
|
+
#### First generate the file
|
85
|
+
|
86
|
+
$ rails generate jpartial
|
87
|
+
|
88
|
+
|
89
|
+
#### Then in `app/config/initializers/jpartial.rb`
|
82
90
|
```ruby
|
83
91
|
Jbuilder::Jpartial.configure do |jpartial|
|
84
92
|
jpartial._post do |post|
|
@@ -89,7 +97,7 @@ Jbuilder::Jpartial.configure do |jpartial|
|
|
89
97
|
json._comment comment
|
90
98
|
end
|
91
99
|
end
|
92
|
-
|
100
|
+
|
93
101
|
jpartial._comment do |comment|
|
94
102
|
json.content comment.content
|
95
103
|
json.author comment.author.name
|
@@ -109,13 +117,13 @@ Notice that when using this method, we don't make any calls like `json.partial!
|
|
109
117
|
We've now cut our template renders down to only 1 from the original 2,550. The only real disadvantage is it bucks the regular Rails file structure conventions for partials. C'est la vie.
|
110
118
|
|
111
119
|
#### How?
|
112
|
-
Each method you call on `jpartial` defines a Jbuilder method of the same name. The objects you will pass to that method are yielded to the block. Inside the block you can use plain old Jbuilder syntax.
|
120
|
+
Each method you call on `jpartial` defines a Jbuilder method of the same name. The objects you will pass to that method are yielded to the block. Inside the block you can use plain old Jbuilder syntax, and access any of the helper methods available in your views.
|
113
121
|
|
114
122
|
e.g.
|
115
123
|
|
116
124
|
```ruby
|
117
125
|
jpartial._post do |post|
|
118
|
-
json.
|
126
|
+
json.post_url post_url(post)
|
119
127
|
end
|
120
128
|
```
|
121
129
|
|
@@ -145,15 +153,16 @@ end
|
|
145
153
|
|
146
154
|
Now you can call `json._post @post, author: @author`
|
147
155
|
|
148
|
-
Again, if you're defining all of your partials in one config file, the extra call to a partial template is not necessary.
|
156
|
+
Again, if you're defining all of your partials in one config file (best performance), the extra call to a partial template is not necessary.
|
149
157
|
|
158
|
+
#### `config/initializers/jpartial.rb`
|
150
159
|
```ruby
|
151
160
|
Jbuilder::Jpartial.configure do |jpartial|
|
152
161
|
jpartial._post do |post, author:|
|
153
162
|
json.title post.title
|
154
163
|
json._author author
|
155
164
|
end
|
156
|
-
|
165
|
+
|
157
166
|
jpartial._author do |author|
|
158
167
|
json.name author.name
|
159
168
|
end
|
@@ -161,11 +170,6 @@ end
|
|
161
170
|
```
|
162
171
|
|
163
172
|
However unlikely, if you try to name a partial with the same name as a method already defined by Jbuilder it will throw an error at start up. Just pick a different name, like `#whatever_partial` instead of `#whatever`.
|
164
|
-
|
165
|
-
Methods taken by this library are `Jbuilder#json` and any valid route helpers defined by your app e.g. `Jbuilder#post_url`. If you have or need any fields with keys like `"json"` or `"post_url"` use `Jbuilder#set!`, e.g.
|
166
|
-
```ruby
|
167
|
-
json.set! 'json', 'some value'
|
168
|
-
json.set! 'post_url', 'some url'
|
169
173
|
```
|
170
174
|
|
171
175
|
|
@@ -183,4 +187,3 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/msimon
|
|
183
187
|
## License
|
184
188
|
|
185
189
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
186
|
-
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails/generators'
|
4
|
+
|
5
|
+
module Jpartial
|
6
|
+
module Generators
|
7
|
+
# Generate a configuration template for partials.
|
8
|
+
class JpartialGenerator < Rails::Generators::Base
|
9
|
+
source_root File.expand_path('../templates', __FILE__)
|
10
|
+
|
11
|
+
def copy_config_file
|
12
|
+
template 'jpartial.rb.erb', 'config/initializers/jpartial.rb'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<%= "# frozen_string_literal: true" %>
|
2
|
+
|
3
|
+
<%= "Jbuilder::Jpartial.configure do |jpartial|" %>
|
4
|
+
<%= "# jpartial._post do |post|" %>
|
5
|
+
<%= "# json.post_url post_url(post)" %>
|
6
|
+
<%= "# json.title post.title" %>
|
7
|
+
<%= "# json.author_name post.author.name" %>
|
8
|
+
<%= "# end" %>
|
9
|
+
<%= "end" %>
|
10
|
+
|
11
|
+
<%= "# In `app/views/posts/show.jbuilder`" %>
|
12
|
+
<%= "# json._post @post" %>
|
13
|
+
<%= "#" %>
|
14
|
+
<%= "# Result:" %>
|
15
|
+
<%= "# {" %>
|
16
|
+
<%= "# \"post_url\": \"http://www.app.com/posts/12345\"," %>
|
17
|
+
<%= "# \"title\": \"The Number One Post\"," %>
|
18
|
+
<%= "# \"author\": \"M. Simon Borg\"" %>
|
19
|
+
<%= "# }" %>
|
data/lib/jbuilder/jpartial.rb
CHANGED
@@ -3,25 +3,6 @@ require 'jbuilder/jpartial/version'
|
|
3
3
|
|
4
4
|
# Top level Jbuilder class
|
5
5
|
class Jbuilder
|
6
|
-
def json
|
7
|
-
self
|
8
|
-
end
|
9
|
-
|
10
|
-
alias_method :old_method_missing, :method_missing
|
11
|
-
|
12
|
-
def method_missing(method_name, *args, &block)
|
13
|
-
if _method_is_a_route_helper?(method_name)
|
14
|
-
@context.send(method_name, *args, &block)
|
15
|
-
else
|
16
|
-
old_method_missing(method_name, *args, &block)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def _method_is_a_route_helper?(method_name)
|
21
|
-
method_name.to_s =~ /(.*)_(url|path)/ && !@context.nil? &&
|
22
|
-
@context.respond_to?(method_name)
|
23
|
-
end
|
24
|
-
|
25
6
|
# Jpartial module
|
26
7
|
module Jpartial
|
27
8
|
DangerousMethodName = Class.new(ArgumentError)
|
@@ -29,18 +10,22 @@ class Jbuilder
|
|
29
10
|
@defined_by_user = []
|
30
11
|
|
31
12
|
def self.jpartial(name, &block)
|
32
|
-
if
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
define_method(name, &block)
|
13
|
+
_raise_dangerous_method_name_error(name) if _dangerous_method_name?(name)
|
14
|
+
JbuilderProxy.class_eval { define_method(name, &block) }
|
15
|
+
Jbuilder.class_eval do
|
16
|
+
define_method(name) do |*args|
|
17
|
+
JbuilderProxy.new(self, @context).__send__(name, *args)
|
38
18
|
end
|
39
|
-
@defined_by_user << name unless @defined_by_user.include?(name)
|
40
19
|
end
|
20
|
+
@defined_by_user << name unless @defined_by_user.include?(name)
|
41
21
|
end
|
42
22
|
|
43
|
-
def self.
|
23
|
+
def self._raise_dangerous_method_name_error(name)
|
24
|
+
raise DangerousMethodName, "The method `##{name}` is already defined"\
|
25
|
+
' by Jbuilder. Please choose another name to define your partial'
|
26
|
+
end
|
27
|
+
|
28
|
+
def self._dangerous_method_name?(name)
|
44
29
|
!@defined_by_user.include?(name) &&
|
45
30
|
Jbuilder.method_defined?(name) ||
|
46
31
|
Jbuilder.private_method_defined?(name)
|
@@ -58,12 +43,41 @@ class Jbuilder
|
|
58
43
|
require 'active_support/basic_object'
|
59
44
|
ActiveSupport::BasicObject
|
60
45
|
end) do
|
61
|
-
|
62
46
|
def method_missing(name, *args, &block)
|
63
47
|
name = name.to_s == 'send' ? args.first.to_sym : name
|
64
48
|
Jpartial.jpartial(name, &block)
|
65
49
|
end
|
66
50
|
end
|
51
|
+
|
52
|
+
# Partial method execution is defined here. Jbuilder only knows how to
|
53
|
+
# initialize an instance of the proxy class and send it the right message.
|
54
|
+
# The proxy is initialized with the execution context if there is any
|
55
|
+
# so it can pass along context methods when they're defined.
|
56
|
+
class JbuilderProxy
|
57
|
+
instance_methods.each do |meth|
|
58
|
+
next if [:method_missing, :__send__, :object_id].include?(meth)
|
59
|
+
undef_method(meth)
|
60
|
+
end
|
61
|
+
|
62
|
+
attr_reader :json
|
63
|
+
|
64
|
+
def initialize(json, context = nil)
|
65
|
+
@json = json
|
66
|
+
@context = context
|
67
|
+
end
|
68
|
+
|
69
|
+
def method_missing(method_name, *args, &block)
|
70
|
+
if _method_defined_in_context?(method_name)
|
71
|
+
@context.send(method_name, *args, &block)
|
72
|
+
else
|
73
|
+
super(method_name, *args, &block)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def _method_defined_in_context?(method_name)
|
78
|
+
!@context.nil? && @context.respond_to?(method_name)
|
79
|
+
end
|
80
|
+
end
|
67
81
|
end
|
68
82
|
end
|
69
83
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jbuilder-jpartial
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- M. Simon Borg
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-07-
|
11
|
+
date: 2017-07-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jbuilder
|
@@ -59,8 +59,11 @@ executables: []
|
|
59
59
|
extensions: []
|
60
60
|
extra_rdoc_files: []
|
61
61
|
files:
|
62
|
+
- CHANGELOG.md
|
62
63
|
- LICENSE.txt
|
63
64
|
- README.md
|
65
|
+
- lib/generators/jpartial_generator.rb
|
66
|
+
- lib/generators/templates/jpartial.rb.erb
|
64
67
|
- lib/jbuilder/jpartial.rb
|
65
68
|
- lib/jbuilder/jpartial/railtie.rb
|
66
69
|
- lib/jbuilder/jpartial/version.rb
|