I understand my question is a bit vague but I don’t know how else to describe it. I’ve asked in numerous places and no one seems to understand why I want to do this. But please bear with me, and I’ll explain why I want something like this.
I’m using Liquid Templates to allow users to make some dynamic pages on my site. And for those that don’t know, Liquid uses a class of theirs called LiquidDrop to expose certain items to the user. Any method in the drop can be called by the Liquid template.
class PageDrop < Liquid::Drop
def initialize(page)
@page = page
end
def name
@page.name
end
def children
PagesDrop.new(@page.children)
end
end
class PagesDrop < Liquid::Drop
def initialize(pages)
@pages = pages
end
def group_by
GroupByDrop.new(@pages)
end
def all
@pages.all
end
def size
@pages.size
end
end
For example, I want to be able to do this:
@page_drop = PageDrop.new(@page) @page_drop.children # to get an array of children
instead of
@page_drop.children.all
Why do I have a pages drop?
Because I want to be able to cleanly split up the methods I can do to an array of pages, and methods I can do to a single page. This allows me to group pages like so:
@page_drop.children.group_by.some_method_here_that_the_group_drop_contains
To make it simpler for my users, I don’t want them to have to think about adding “all” or not to a drop instance to get the “default” object/s that it contains. To reiterate:
@pages_drop = PagesDrop.new(Page.all) @pages_drop == @pages_drop.pages #I want this to be true, as well as @pages_drop == @pages_drop.all
Where did I get this idea?
In Rails, a scope (association object) (@person.friends) seems to return the array when you do certain things to it: @person.friends.each, for person in @person.friends
This isn’t really possible. When you write
@instanceyou aren’t really calling an instance as you describe, you’re getting a reference to the object that@instancerefers to.The reason it seems to work with the collections for Rails’ associations is that the the association objects are instances of
Arraythat have had some of their methods overridden.I would consider removing
PagesDropand using thegroup_by(&:method)syntax if you want a concise way to express groupings. If you do want to keep it then you can get some way towards what you want by implementingeachand[]onPagesDropand having them delegate to@pages. That will let you use@page_drop.childreninforloops, for instance.