Skip to content

Commit

Permalink
Add partials
Browse files Browse the repository at this point in the history
Signed-off-by: Jordan Hollinger <[email protected]>
  • Loading branch information
jhollinger committed Aug 24, 2024
1 parent aea8647 commit c2db5e5
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 2 deletions.
1 change: 1 addition & 0 deletions lib/blueprinter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module Blueprinter
autoload :Extension, 'blueprinter/extension'
autoload :Transformer, 'blueprinter/transformer'
autoload :V2, 'blueprinter/v2'
autoload :V3, 'blueprinter/v3'

class << self
# @return [Configuration]
Expand Down
1 change: 1 addition & 0 deletions lib/blueprinter/errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
module Blueprinter
module Errors
autoload :InvalidBlueprint, 'blueprinter/errors/invalid_blueprint'
autoload :UnknownPartial, 'blueprinter/errors/unknown_partial'
autoload :UnknownView, 'blueprinter/errors/unknown_view'
end
end
7 changes: 7 additions & 0 deletions lib/blueprinter/errors/unknown_partial.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

module Blueprinter
module Errors
class UnknownPartial < Blueprinter::BlueprinterError; end
end
end
4 changes: 3 additions & 1 deletion lib/blueprinter/v2.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ class V2
extend Reflection

class << self
attr_accessor :views, :fields, :extensions, :options
attr_accessor :views, :fields, :partials, :extensions, :options
# The fully-qualified name, e.g. "MyBlueprint", or "MyBlueprint.foo.bar"
attr_accessor :blueprint_name
end

self.views = {}
self.fields = {}
self.partials = {}
self.extensions = []
self.options = Options.new(DEFAULT_OPTIONS)
self.blueprint_name = name
Expand All @@ -26,6 +27,7 @@ class << self
def self.inherited(subclass)
subclass.views = { default: subclass }
subclass.fields = fields.transform_values(&:dup)
subclass.partials = partials.dup
subclass.extensions = extensions.dup
subclass.options = options.dup
subclass.blueprint_name = subclass.name || blueprint_name
Expand Down
30 changes: 29 additions & 1 deletion lib/blueprinter/v2/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,30 @@ def view(name, &definition)
views[name.to_sym] = view
end

#
# Define a new partial.
#
# @param name [Symbol] Name of the partial to create or import
# @yield Define a new partial in the block
#
def partial(name, &definition)
partials[name.to_sym] = definition
end

#
# Import a partial into this view.
#
# @param name [Array<Symbol>] One or more partial names
#
def use(*names)
names.each do |name|
if !(p = partials[name])
raise Errors::UnknownPartial, "Partial '#{name}' could not be found in Blueprint '#{self}'. NOTE: partials must be defined before your views!"
end
class_eval(&p)
end
end

#
# Define a field.
#
Expand Down Expand Up @@ -67,7 +91,11 @@ def association(name, blueprint, from: name, view: nil, **options, &definition)
)
end

# Exclude parent fields/associations from inheritance
#
# Exclude parent fields and associations from this view.
#
# @param name [Array<Symbol>] One or more fields or associations to exclude
#
def exclude(*names)
unknown = []
names.each do |name|
Expand Down
41 changes: 41 additions & 0 deletions spec/v2/partials_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# frozen_string_literal: true

describe "Blueprinter::V2 Partials" do
it "should allow a partial to be used in any view" do
blueprint = Class.new(Blueprinter::V2) do
field :name

partial :description do
field :description
end

view :foo do
use :description
end

view :bar do
use :description
end
end

expect(blueprint.reflections[:default].fields.keys).to eq %i(name)
expect(blueprint.reflections[:foo].fields.keys.sort).to eq %i(
name
description
).sort
expect(blueprint.reflections[:bar].fields.keys.sort).to eq %i(
name
description
).sort
end

it "should throw an error for an invalid partial name" do
expect do
Class.new(Blueprinter::V2) do
view :foo do
use :description
end
end
end.to raise_error(Blueprinter::Errors::UnknownPartial)
end
end

0 comments on commit c2db5e5

Please sign in to comment.