jump to navigation

Passing Hashes to Partials September 13, 2007

Posted by reidmix in Code, Example, Hash, Partial, Rails, Ruby, SimpleDelegator.

Sometimes you need to pass a Hash or collection of Hashes to a partial. In either case, when render tries to determine if you are using the old style method (render_partial) or the new style. When it comes across your hash, rails believes it’s dealing with all your supplied parameters to render. You can see this logic in action_view/partials.rb:

module ActionView
	module Partials
		def render_partial(partial_path, local_assigns = nil, deprecated_local_assigns = nil) #:nodoc:
			path, partial_name = partial_pieces(partial_path)
			object = extracting_object(partial_name, local_assigns, deprecated_local_assigns)
			local_assigns = extract_local_assigns(local_assigns, deprecated_local_assigns)
			local_assigns = local_assigns ? local_assigns.clone : {}

You can see the last line shown in the method, where if it can’t determine a local_assigns, it just uses an empty Hash. And so that’s how it surfaces, you pass your Hash to the partial and nothing gets rendered. What we need to do is disguise that we are passing a Hash but have all the functionality of one.

Ruby gives us a few options but the easiest is SimpleDelegator. All we need to do is pass our object upon initialization and SimpleDelegator will delegate all methods to that object:

myhash = { :a => "test1", :b => "test2" }
d = SimpleDelegator.new(myhash)
puts d[:a] # => test1

If sometimes have collections of Hashes (or Hashes mixed in with my collection), I employ the following pattern:

collection = [collection] unless collection.is_a? Array
collection = collection.collect { |i| (i.is_a? Hash) ? SimpleDelegator.new(i) : i }
render :partial => "mypartial", :object => collection.compat


No comments yet — be the first.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: