if the following tag is ['first','last' or 'size] defer to_liquid #145

wants to merge 1 commit into


None yet

3 participants


@ssoroka @Soleone Please Review /cc @hornairs

Currently, if a liquid user executes collection.products.first, products will be converted to_liquid before the .first is applied.

If the drop provides an ActiveRelation object to the liquid engine, calling .to_liquid on the ActiveRelation will load all the objects, and then throw out all but the first.

If we defer calling .to_liquid until after we've applied .first then ActiveRecord will do the right thing and only load the single product.

This fix is a first-principals approach to solving the problem: if the following tag is in ['first', 'last', 'size'] and we've got an object that responds to the tag, send it before rendering to_liquid.

I feel like there's potential for a bigger refactor here, to recursively apply the following tags and only render .to_liquid when necessary.


I like where you're going with this, but I think this exposes security holes. A better option might be to pass RelationDrops around that preserve the relation.


@ssoroka Ah I see. Drop#to_liquid returns the drop itself so the relation can be maintained. That's definitely a better approach, will rewrite.

@boourns boourns closed this Oct 1, 2012
@tobi tobi commented on the diff Oct 2, 2012
@@ -204,8 +204,10 @@ def variable(markup)
if object = find_variable(first_part)
+ i = 0
+ while i < parts.length
tobi Oct 2, 2012

stylisitically this should be a parts.length.times do |i| ... end loop.

@tobi tobi commented on the diff Oct 2, 2012
- parts.each do |part|
tobi Oct 2, 2012

or even parts.each_with_index do |part, i|

Shopify member

Agreed with @snookca. A better approach would be to add a .to_liquid method for relations that returns a drop.

@fw42 fw42 deleted the defer_object_to_liquid branch Jul 28, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment