Skip to content

Commit

Permalink
Adds support for better formatted children in xml via child_root
Browse files Browse the repository at this point in the history
  • Loading branch information
nesquena committed Apr 27, 2011
1 parent b6bb44b commit 7065793
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 10 deletions.
4 changes: 3 additions & 1 deletion lib/rabl/builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ class Builder
include Rabl::Helpers

# Constructs a new ejs hash based on given object and options
# options = { :format => "json", :attributes, :root => true,
# :child_root => true, :code, :child, :glue, :extends }
def initialize(data, options={}, &block)
@options = options
@_scope = options[:scope]
Expand Down Expand Up @@ -70,7 +72,7 @@ def code(name, options={}, &block)
def child(data, options={}, &block)
return false unless data.present?
name, object = data_name(data), data_object(data)
include_root = object.respond_to?(:each) # child @users
include_root = object.respond_to?(:each) && @options[:child_root] # child @users
object = { object => name } if data.respond_to?(:each_pair) && object # child :users => :people
@_result[name] = self.object_to_hash(object, :root => include_root, &block) if resolve_condition(options)
end
Expand Down
25 changes: 18 additions & 7 deletions lib/rabl/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class Engine
# Rabl::Engine.new("...source...", { :format => "xml", :root => true, :view_path => "/path/to/views" })
def initialize(source, options={})
@_source = source
@_options = options.reverse_merge(:format => "json")
@_options = options
end

# Renders the representation based on source, object, scope and locals
Expand All @@ -15,36 +15,38 @@ def render(scope, locals, &block)
@_locals, @_scope = locals, scope
self.copy_instance_variables_from(@_scope, [:@assigns, :@helpers])
@_options[:scope] = @_scope
@_options[:format] ||= default_format
@_data = locals[:object] || self.default_object
instance_eval(@_source) if @_source.present?
instance_eval(&block) if block_given?
self.send("to_" + @_options[:format].to_s)
end

# Returns a hash representation of the data object
# to_hash(:root => true)
# to_hash(:root => true, :child_root => true)
def to_hash(options={})
options = options.reverse_merge(@_options)
data = data_object(@_data)
if is_record?(data) || !data # object @user
Rabl::Builder.new(@_data, @_options).to_hash(options)
Rabl::Builder.new(@_data, options).to_hash(options)
elsif data.respond_to?(:each) # collection @users
object_name = data_name(@_data).to_s.singularize # @users => :users
data.map { |object| Rabl::Builder.new({ object => object_name }, @_options).to_hash(options) }
data.map { |object| Rabl::Builder.new({ object => object_name }, options).to_hash(options) }
end
end

# Returns a json representation of the data object
# to_json(:root => true)
def to_json(options={})
options = options.reverse_merge(:root => true)
options = options.reverse_merge(:root => true, :child_root => true)
result = @_collection_name ? { @_collection_name => to_hash(options) } : to_hash(options)
result.to_json
end

# Returns a json representation of the data object
# Returns an xml representation of the data object
# to_xml(:root => true)
def to_xml(options={})
options = options.reverse_merge(:root => false)
options = options.reverse_merge(:root => false, :child_root => false)
to_hash(options).to_xml(:root => data_name(@_data))
end

Expand Down Expand Up @@ -124,5 +126,14 @@ def default_object
instance_variable_get("@#{@_scope.controller.controller_name}") :
nil
end

# Returns a guess at the format in this scope
# default_format => "xml"
def default_format
format = @_scope.respond_to?(:params) && @_scope.params.has_key?(:format) ?
@_scope.params[:format] :
nil
format || "json"
end
end
end
13 changes: 11 additions & 2 deletions test/builder_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,23 @@
get_result(b)
end.equivalent_to({ :user => 'xyz'})

asserts "that it generates with an collection" do
b = builder @user, {}
asserts "that it generates with an collection and child_root" do
b = builder @user, { :child_root => true }
mock(b).data_name(@users) { :users }
mock(b).object_to_hash(@users,{ :root => true }).returns('xyz').subject

b.child(@users) { attribute :name }
get_result(b)
end.equivalent_to({ :users => 'xyz'})

asserts "that it generates with an collection and no child root" do
b = builder @user, { :child_root => false }
mock(b).data_name(@users) { :users }
mock(b).object_to_hash(@users,{ :root => false }).returns('xyz').subject

b.child(@users) { attribute :name }
get_result(b)
end.equivalent_to({ :users => 'xyz'})
end

context "#glue" do
Expand Down

0 comments on commit 7065793

Please sign in to comment.