@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.
['first', 'last', 'size']
I feel like there's potential for a bigger refactor here, to recursively apply the following tags and only render .to_liquid when necessary.
if the following tag is ['first','last' or 'size] defer to_liquid
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.
stylisitically this should be a parts.length.times do |i| ... end loop.
or even parts.each_with_index do |part, i|
Agreed with @snookca. A better approach would be to add a .to_liquid method for relations that returns a drop.