Skip to content

Cleanup project for Rails 7+ support #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
May 29, 2025
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
6 changes: 3 additions & 3 deletions jbuilder.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ Gem::Specification.new do |s|
s.homepage = 'https://github.com/rails/jbuilder'
s.license = 'MIT'

s.required_ruby_version = '>= 2.2.2'
s.required_ruby_version = '>= 3.0.0'

s.add_dependency 'activesupport', '>= 5.0.0'
s.add_dependency 'actionview', '>= 5.0.0'
s.add_dependency 'activesupport', '>= 7.0.0'
s.add_dependency 'actionview', '>= 7.0.0'

if RUBY_ENGINE == 'rbx'
s.add_development_dependency('racc')
Expand Down
94 changes: 17 additions & 77 deletions lib/jbuilder/collection_renderer.rb
Original file line number Diff line number Diff line change
@@ -1,37 +1,9 @@
require 'delegate'
require 'active_support/concern'
require 'action_view'

begin
require 'action_view/renderer/collection_renderer'
rescue LoadError
require 'action_view/renderer/partial_renderer'
end
require 'action_view/renderer/collection_renderer'

class Jbuilder
module CollectionRenderable # :nodoc:
extend ActiveSupport::Concern

class_methods do
def supported?
superclass.private_method_defined?(:build_rendered_template) && self.superclass.private_method_defined?(:build_rendered_collection)
end
end

private

def build_rendered_template(content, template, layout = nil)
super(content || json.attributes!, template)
end

def build_rendered_collection(templates, _spacer)
json.merge!(templates.map(&:body))
end

def json
@options[:locals].fetch(:json)
end

class CollectionRenderer < ::ActionView::CollectionRenderer # :nodoc:
class ScopedIterator < ::SimpleDelegator # :nodoc:
include Enumerable

Expand All @@ -40,16 +12,6 @@ def initialize(obj, scope)
@scope = scope
end

# Rails 6.0 support:
def each
return enum_for(:each) unless block_given?

__getobj__.each do |object|
@scope.call { yield(object) }
end
end

# Rails 6.1 support:
Copy link

@Insomniak47 Insomniak47 May 29, 2025

Choose a reason for hiding this comment

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

Is this func still needed then?

(the each_with_info func)

Copy link
Author

Choose a reason for hiding this comment

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

It is. It really should have said "Rails >= 6.1 support".

def each_with_info
return enum_for(:each_with_info) unless block_given?

Expand All @@ -60,51 +22,29 @@ def each_with_info
end

private_constant :ScopedIterator
end

if defined?(::ActionView::CollectionRenderer)
# Rails 6.1 support:
class CollectionRenderer < ::ActionView::CollectionRenderer # :nodoc:
include CollectionRenderable

def initialize(lookup_context, options, &scope)
super(lookup_context, options)
@scope = scope
end

private
def collection_with_template(view, template, layout, collection)
super(view, template, layout, ScopedIterator.new(collection, @scope))
end
def initialize(lookup_context, options, &scope)

Choose a reason for hiding this comment

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

This initialize was part of CollectionRenderer - since you're removing its definition is this initialize still needed?

Copy link
Author

Choose a reason for hiding this comment

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

CollectionRenderer is still being defined. The PR is removing the CollectionRenderer defined for < Rails 6.1.

class CollectionRenderer < ::ActionView::PartialRenderer is gone.
class CollectionRenderer < ::ActionView::CollectionRenderer remains.

CollectionRenderer was being conditionally defined via if defined?(::ActionView::CollectionRenderer)

Choose a reason for hiding this comment

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

So this is still needed?

super(lookup_context, options)
@scope = scope
end
else
# Rails 6.0 support:
class CollectionRenderer < ::ActionView::PartialRenderer # :nodoc:
include CollectionRenderable

def initialize(lookup_context, options, &scope)
super(lookup_context)
@options = options
@scope = scope
end
private

def render_collection_with_partial(collection, partial, context, block)
render(context, @options.merge(collection: collection, partial: partial), block)
def build_rendered_template(content, template, layout = nil)
super(content || json.attributes!, template)
end

private
def collection_without_template(view)
@collection = ScopedIterator.new(@collection, @scope)

super(view)
end
def build_rendered_collection(templates, _spacer)
json.merge!(templates.map(&:body))
end

def collection_with_template(view, template)
@collection = ScopedIterator.new(@collection, @scope)
def json
@options[:locals].fetch(:json)
end

super(view, template)
end
end
def collection_with_template(view, template, layout, collection)
super(view, template, layout, ScopedIterator.new(collection, @scope))
end
end

class EnumerableCompat < ::SimpleDelegator
Expand Down
18 changes: 1 addition & 17 deletions lib/jbuilder/jbuilder_template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ def _render_partial_with_options(options)
options.reverse_merge! ::JbuilderTemplate.template_lookup_options
as = options[:as]

if as && options.key?(:collection) && CollectionRenderer.supported?
if as && options.key?(:collection)
collection = options.delete(:collection) || []
partial = options.delete(:partial)
options[:locals].merge!(json: self)
Expand All @@ -164,22 +164,6 @@ def _render_partial_with_options(options)
else
array!
end
elsif as && options.key?(:collection) && !CollectionRenderer.supported?
# For Rails <= 5.2:
as = as.to_sym
collection = options.delete(:collection)

if collection.present?
locals = options.delete(:locals)
array! collection do |member|
member_locals = locals.clone
member_locals.merge! collection: collection
member_locals.merge! as => member
_render_partial options.merge(locals: member_locals)
end
else
array!
end
else
_render_partial options
end
Expand Down
28 changes: 12 additions & 16 deletions lib/jbuilder/railtie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,24 @@ class Railtie < ::Rails::Railtie
require 'jbuilder/jbuilder_dependency_tracker'
end

if Rails::VERSION::MAJOR >= 5
module ::ActionController
module ApiRendering
include ActionView::Rendering
end
module ::ActionController
module ApiRendering
include ActionView::Rendering
end
end

ActiveSupport.on_load :action_controller do
if name == 'ActionController::API'
include ActionController::Helpers
include ActionController::ImplicitRender
end
ActiveSupport.on_load :action_controller do
if name == 'ActionController::API'
include ActionController::Helpers
include ActionController::ImplicitRender
end
end
end

if Rails::VERSION::MAJOR >= 4
generators do |app|
Rails::Generators.configure! app.config.generators
Rails::Generators.hidden_namespaces.uniq!
require 'generators/rails/scaffold_controller_generator'
end
generators do |app|
Rails::Generators.configure! app.config.generators
Rails::Generators.hidden_namespaces.uniq!
require 'generators/rails/scaffold_controller_generator'
end
end
end
14 changes: 6 additions & 8 deletions test/jbuilder_generator_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,13 @@ class JbuilderGeneratorTest < Rails::Generators::TestCase
end
end

if Rails::VERSION::MAJOR >= 6
test 'handles virtual attributes' do
run_generator %w(Message content:rich_text video:attachment photos:attachments)
test 'handles virtual attributes' do
run_generator %w(Message content:rich_text video:attachment photos:attachments)

assert_file 'app/views/messages/_message.json.jbuilder' do |content|
assert_match %r{json\.content message\.content\.to_s}, content
assert_match %r{json\.video url_for\(message\.video\)}, content
assert_match %r{json\.photos do\n json\.array!\(message\.photos\) do \|photo\|\n json\.id photo\.id\n json\.url url_for\(photo\)\n end\nend}, content
end
assert_file 'app/views/messages/_message.json.jbuilder' do |content|
assert_match %r{json\.content message\.content\.to_s}, content
assert_match %r{json\.video url_for\(message\.video\)}, content
assert_match %r{json\.photos do\n json\.array!\(message\.photos\) do \|photo\|\n json\.id photo\.id\n json\.url url_for\(photo\)\n end\nend}, content
end
end
end
Loading