From 86b394640a186f65f2ee194428e750d7d483d263 Mon Sep 17 00:00:00 2001 From: Michael Oberegger Date: Thu, 8 May 2025 15:29:43 -0400 Subject: [PATCH 01/10] Optimize options merging --- lib/jbuilder/jbuilder_template.rb | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/lib/jbuilder/jbuilder_template.rb b/lib/jbuilder/jbuilder_template.rb index 55f2d5f..c929c6a 100644 --- a/lib/jbuilder/jbuilder_template.rb +++ b/lib/jbuilder/jbuilder_template.rb @@ -4,11 +4,7 @@ require 'active_support/cache' class JbuilderTemplate < Jbuilder - class << self - attr_accessor :template_lookup_options - end - - self.template_lookup_options = { handlers: [:jbuilder] } + HANDLERS = [:jbuilder].freeze def initialize(context, *args) @context = context @@ -137,14 +133,14 @@ def set!(name, object = BLANK, *args) private def _render_partial_with_options(options) - options.reverse_merge! locals: options.except(:partial, :as, :collection, :cached) - options.reverse_merge! ::JbuilderTemplate.template_lookup_options + options[:locals] ||= options.except(:partial, :as, :collection, :cached) + options[:handlers] ||= ::JbuilderTemplate::HANDLERS as = options[:as] if as && options.key?(:collection) && CollectionRenderer.supported? collection = options.delete(:collection) || [] partial = options.delete(:partial) - options[:locals].merge!(json: self) + options[:locals][:json] = self collection = EnumerableCompat.new(collection) if collection.respond_to?(:count) && !collection.respond_to?(:size) if options.has_key?(:layout) @@ -173,8 +169,8 @@ def _render_partial_with_options(options) locals = options.delete(:locals) array! collection do |member| member_locals = locals.clone - member_locals.merge! collection: collection - member_locals.merge! as => member + member_locals[:collection] = collection + member_locals[as] = member _render_partial options.merge(locals: member_locals) end else @@ -186,7 +182,7 @@ def _render_partial_with_options(options) end def _render_partial(options) - options[:locals].merge! json: self + options[:locals][:json] = self @context.render options end From 866d2892c2b9fe4c407cb4437f954afd9637d8c3 Mon Sep 17 00:00:00 2001 From: Michael Oberegger Date: Fri, 9 May 2025 12:31:03 -0400 Subject: [PATCH 02/10] Call _set_value directly --- lib/jbuilder/jbuilder_template.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/jbuilder/jbuilder_template.rb b/lib/jbuilder/jbuilder_template.rb index c929c6a..5228d5a 100644 --- a/lib/jbuilder/jbuilder_template.rb +++ b/lib/jbuilder/jbuilder_template.rb @@ -244,7 +244,7 @@ def _set_inline_partial(name, object, options) _scope{ _render_partial_with_options options.merge(locals: locals) } end - set! name, value + _set_value name, value end def _render_explicit_partial(name_or_options, locals = {}) From c6b9bffed86c5a8dbdab0e475c92377b7eec1387 Mon Sep 17 00:00:00 2001 From: Michael Oberegger Date: Mon, 12 May 2025 11:48:07 -0400 Subject: [PATCH 03/10] Put template_lookup_options to avoid possible breaking change --- lib/jbuilder/jbuilder_template.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/jbuilder/jbuilder_template.rb b/lib/jbuilder/jbuilder_template.rb index 5228d5a..b4ba87e 100644 --- a/lib/jbuilder/jbuilder_template.rb +++ b/lib/jbuilder/jbuilder_template.rb @@ -4,7 +4,11 @@ require 'active_support/cache' class JbuilderTemplate < Jbuilder - HANDLERS = [:jbuilder].freeze + class << self + attr_accessor :template_lookup_options + end + + self.template_lookup_options = { handlers: [:jbuilder] } def initialize(context, *args) @context = context @@ -134,7 +138,7 @@ def set!(name, object = BLANK, *args) def _render_partial_with_options(options) options[:locals] ||= options.except(:partial, :as, :collection, :cached) - options[:handlers] ||= ::JbuilderTemplate::HANDLERS + options[:handlers] ||= ::JbuilderTemplate.template_lookup_options[:handlers] as = options[:as] if as && options.key?(:collection) && CollectionRenderer.supported? From ba3a6274a9827773769f24a39956358059be7d11 Mon Sep 17 00:00:00 2001 From: Michael Oberegger Date: Mon, 12 May 2025 12:13:21 -0400 Subject: [PATCH 04/10] Save on more merges --- lib/jbuilder/jbuilder_template.rb | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/lib/jbuilder/jbuilder_template.rb b/lib/jbuilder/jbuilder_template.rb index b4ba87e..3dac041 100644 --- a/lib/jbuilder/jbuilder_template.rb +++ b/lib/jbuilder/jbuilder_template.rb @@ -118,7 +118,8 @@ def array!(collection = [], *args) options = args.first if args.one? && _partial_options?(options) - partial! options.merge(collection: collection) + options[:collection] = collection + partial! options else super end @@ -175,7 +176,8 @@ def _render_partial_with_options(options) member_locals = locals.clone member_locals[:collection] = collection member_locals[as] = member - _render_partial options.merge(locals: member_locals) + options[:locals] = member_locals + _render_partial options end else array! @@ -242,10 +244,16 @@ def _set_inline_partial(name, object, options) value = if object.nil? [] elsif _is_collection?(object) - _scope{ _render_partial_with_options options.merge(collection: object) } + _scope do + options[:collection] = object + _render_partial_with_options options + end else locals = ::Hash[options[:as], object] - _scope{ _render_partial_with_options options.merge(locals: locals) } + _scope do + options[:locals] = locals + _render_partial_with_options options + end end _set_value name, value @@ -259,7 +267,8 @@ def _render_explicit_partial(name_or_options, locals = {}) else # partial! 'name', locals: {foo: 'bar'} if locals.one? && (locals.keys.first == :locals) - options = locals.merge(partial: name_or_options) + locals[:partial] = name_or_options + options = locals else options = { partial: name_or_options, locals: locals } end From 9ca4d0526996d1dfc6e97f1f9ccbc8d971581038 Mon Sep 17 00:00:00 2001 From: Michael Oberegger Date: Mon, 12 May 2025 16:50:23 -0400 Subject: [PATCH 05/10] Save memory allocation when calling render --- lib/jbuilder/jbuilder_template.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/jbuilder/jbuilder_template.rb b/lib/jbuilder/jbuilder_template.rb index 3dac041..74ed66e 100644 --- a/lib/jbuilder/jbuilder_template.rb +++ b/lib/jbuilder/jbuilder_template.rb @@ -189,7 +189,7 @@ def _render_partial_with_options(options) def _render_partial(options) options[:locals][:json] = self - @context.render options + @context.render options, nil end def _cache_fragment_for(key, options, &block) From 8f9993a3daadd60919a36c3df885fccd97992ce2 Mon Sep 17 00:00:00 2001 From: Michael Oberegger Date: Mon, 21 Jul 2025 14:59:54 -0400 Subject: [PATCH 06/10] Stop mutating options in array! method --- lib/jbuilder/jbuilder_template.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/jbuilder/jbuilder_template.rb b/lib/jbuilder/jbuilder_template.rb index e165ef6..44219f3 100644 --- a/lib/jbuilder/jbuilder_template.rb +++ b/lib/jbuilder/jbuilder_template.rb @@ -121,8 +121,9 @@ def array!(collection = [], *args) options = args.first if args.one? && _partial_options?(options) + options = options.dup options[:collection] = collection - partial! options + _render_partial_with_options options else super end From 8474b41f666b13055b9368107c783cdae7903fb6 Mon Sep 17 00:00:00 2001 From: Michael Oberegger Date: Mon, 21 Jul 2025 15:31:57 -0400 Subject: [PATCH 07/10] Remove _partial micro-optimization --- lib/jbuilder/jbuilder_template.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/jbuilder/jbuilder_template.rb b/lib/jbuilder/jbuilder_template.rb index 44219f3..1d1afdc 100644 --- a/lib/jbuilder/jbuilder_template.rb +++ b/lib/jbuilder/jbuilder_template.rb @@ -178,7 +178,7 @@ def _render_partial_with_options(options) def _render_partial(options) options[:locals][:json] = self - @context.render options, nil + @context.render options end def _cache_fragment_for(key, options, &block) From 7e16adf446c9da701e1e5fdbe9c93f7f8095630d Mon Sep 17 00:00:00 2001 From: Michael Oberegger Date: Wed, 23 Jul 2025 14:05:41 -0400 Subject: [PATCH 08/10] Stop mutating options in set! method --- lib/jbuilder/jbuilder_template.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/jbuilder/jbuilder_template.rb b/lib/jbuilder/jbuilder_template.rb index 1d1afdc..5b64e5a 100644 --- a/lib/jbuilder/jbuilder_template.rb +++ b/lib/jbuilder/jbuilder_template.rb @@ -133,7 +133,7 @@ def set!(name, object = BLANK, *args) options = args.first if args.one? && _partial_options?(options) - _set_inline_partial name, object, options + _set_inline_partial name, object, options.dup else super end From b7b5abb02d9bb2ed1fc584a08142838a05cafc08 Mon Sep 17 00:00:00 2001 From: Michael Oberegger Date: Wed, 23 Jul 2025 14:05:51 -0400 Subject: [PATCH 09/10] Stop mutating options in partial! method --- lib/jbuilder/jbuilder_template.rb | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/lib/jbuilder/jbuilder_template.rb b/lib/jbuilder/jbuilder_template.rb index 5b64e5a..a44cc2c 100644 --- a/lib/jbuilder/jbuilder_template.rb +++ b/lib/jbuilder/jbuilder_template.rb @@ -55,7 +55,9 @@ def partial!(*args) if args.one? && _is_active_model?(args.first) _render_active_model_partial args.first else - _render_explicit_partial(*args) + options = args.extract_options!.dup + options[:partial] = args.first if args.present? + _render_partial_with_options options end end @@ -248,28 +250,6 @@ def _set_inline_partial(name, object, options) _set_value name, value end - def _render_explicit_partial(name_or_options, locals = {}) - case name_or_options - when ::Hash - # partial! partial: 'name', foo: 'bar' - options = name_or_options - else - # partial! 'name', locals: {foo: 'bar'} - if locals.one? && (locals.keys.first == :locals) - locals[:partial] = name_or_options - options = locals - else - options = { partial: name_or_options, locals: locals } - end - # partial! 'name', foo: 'bar' - as = locals.delete(:as) - options[:as] = as if as.present? - options[:collection] = locals[:collection] if locals.key?(:collection) - end - - _render_partial_with_options options - end - def _render_active_model_partial(object) @context.render object, json: self end From 6fd6c0662f6507be951ba842857c663adb000f56 Mon Sep 17 00:00:00 2001 From: Michael Oberegger Date: Wed, 23 Jul 2025 14:07:19 -0400 Subject: [PATCH 10/10] Small _set_inline_partial optimization --- lib/jbuilder/jbuilder_template.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/jbuilder/jbuilder_template.rb b/lib/jbuilder/jbuilder_template.rb index a44cc2c..855dd67 100644 --- a/lib/jbuilder/jbuilder_template.rb +++ b/lib/jbuilder/jbuilder_template.rb @@ -240,9 +240,8 @@ def _set_inline_partial(name, object, options) _render_partial_with_options options end else - locals = ::Hash[options[:as], object] _scope do - options[:locals] = locals + options[:locals] = { options[:as] => object } _render_partial_with_options options end end