Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #11491 (closed enhancement: fixed)

Opened 8 months ago

Last modified 8 months ago

[PATCH] render partial collection (shorthand) with different types of records

Reported by: zdennis Assigned to: core
Priority: normal Milestone: 2.x
Component: ActionPack Version: edge
Severity: normal Keywords: render, partial, collection
Cc:

Description

Currently when using the shorthand for rendering partial collections it assumes that each element of your collection is of the same type, and it assumes that you want to render the same partial for each element. It does this by using the first element of the collection to find a partial to render. For example:

# Say you have the following models using STI: Record, LogRecord, AuditRecord

# In controller
@records = Record.find(:all)   # this returns array of Record, LogRecord and AuditRecords

# In your view template
render :partial => @records

Whatever @records.first returns will be used to determine what partial to render, and that partial will be used for rendering each element of the collection. This seems like the wrong behavior.

The attached patch updates the shorthand to render the correct partial for each element in the collection. It locally caches the PartialTemplates used while rendering a collection so if you have 50 LogRecords and 50 AuditRecords in a single collection it will create two PartialTemplates and re-use them.

The counters that are automatically accessible to each partial still work. As an example say you render the following:

render :partial => [ someLogRecord, someAuditRecord, anotherAuditRecord, anotherLogRecord ]
  • The first render will go to log_records/_log_record.html.erb with a log_record_counter set to 1
  • The second render will go to audit_records/_audit_record.html.erb with a audit_record_counter set to 2
  • The third render will go to audit_records/_audit_record.html.erb with a audit_record_counter set to 3
  • The fourth render will go to log_records/_log_record.html.erb with a log_record_counter set to 4

This only works when using the *shorthand* for rendering partials. If you want to explicitly render the same partial for a collection regardless of what's in it then you can still explicitly give a partial:

render :partial => "log_records/log_record", :collection => [ someAuditRecord, someLogRecord ]

The attached patch includes tests.

Use Cases

Log Records

Log records are a good choice for STI. To find all log records associated with a Project and display them it may require that you render slightly different partials for each kind of log record. Using the updated shorthand you are able to do this without any conditional code in the view (or helper modules), it just works.

On a More General Note

This patch has a broad scope of use-cases. Anything that uses STI could benefit if the display of each kind of record slightly differs. Even outside of STI you can render a collection of any number of objects and trust that the right partial will be renderer for each partial.

With this patch you don't lose existing behavior. Instead you add to the "convention" ideal and make lives simpler for developers.

Attachments

render_partial_collection_with_multiple_element_types.patch (6.1 kB) - added by zdennis on 04/01/08 00:28:09.
Patch to allow render partial => collection work with different types of records

Change History

04/01/08 00:28:09 changed by zdennis

  • attachment render_partial_collection_with_multiple_element_types.patch added.

Patch to allow render partial => collection work with different types of records

04/01/08 00:50:12 changed by bitsweat

  • status changed from new to closed.
  • resolution set to fixed.

(In [9177]) Support render :partial => collection of heterogeneous elements. Closes #11491.

04/01/08 00:57:05 changed by bitsweat

(In [9178]) Missed adds. References #11491.

04/01/08 02:09:18 changed by pratik

(In [9179]) Remove unnecessary arguments. References #11491.