Ruby / Rails:调用实例时是否可以执行默认方法(@instance == @ instance.all IF“all”是默认方法)?

时间:2010-10-21 10:08:35

标签: ruby-on-rails ruby liquid

我理解我的问题有点模糊,但我不知道如何描述它。我曾在很多地方问过,似乎没有人理解我为什么要这样做。但请耐心等待,我会解释为什么我想要这样的东西。

我正在使用Liquid Templates来允许用户在我的网站上制作一些动态页面。对于那些不知道的人,Liquid使用他们称为LiquidDrop的一类来向用户公开某些项目。 Drop中的任何方法都可以通过Liquid模板调用。

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

例如,我希望能够这样做:

@page_drop = PageDrop.new(@page)
@page_drop.children # to get an array of children

而不是

@page_drop.children.all

为什么我的页面会丢失?

因为我希望能够干净地将我可以对一组页面执行的方法拆分,以及我可以对单个页面执行的方法。这允许我像这样分组页面:

@page_drop.children.group_by.some_method_here_that_the_group_drop_contains

为了让我的用户更简单,我不希望他们不得不考虑将“all”添加到drop实例中以获取它包含的“default”对象。重申:

@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

我从哪里得到这个想法?

在Rails中,范围(关联对象)(@ person.friends)似乎在你做某些事情时返回数组:@ person.friends.each,对于@ person.friends中的人

2 个答案:

答案 0 :(得分:1)

这实际上是不可能的。当您编写@instance时,您并未真正按照您的描述调用实例,而是获得@instance引用的对象的引用。

它似乎与Rails关联的集合一起使用的原因是关联对象是Array的实例,它们已经覆盖了一些方法。

如果您想要一种简洁的方式来表达分组,我会考虑删除PagesDrop并使用group_by(&:method)语法。如果您确实希望保留它,那么您可以通过在each上实施[]PagesDrop并让他们委托给@pages来实现您想要的目标。例如,这将允许您在@page_drop.children循环中使用for

答案 1 :(得分:0)

看起来你想在rails之外实现has_many。以下是否有效?

class PageDrop < Liquid::Drop
  attr_accessor :children
  def initialize(page)
    @page = page
    @children = []
  end

  def name
    @page.name
  end
end

这允许您执行以下操作:

@page_drop = PageDrop.new(@page)
@page_drop.children.size # => 0
@page_drop.children # => []

这也为您提供了所有标准数组函数(group_by,size,each等)。如果要添加自己的方法,请创建一个继承自Array的类,并在那里添加方法。

class PageArray < Array
   def my_method
     self.each{|a| puts a}
   end
end

class PageDrop < Liquid::Drop
  attr_accessor :children
  def initialize(page)
    @page = page
    @children = PageArray.new
  end
  [...]
end

@page_drop = PageDrop.new(@page)
@page_drop.children.size # => 0
@page_drop.children # => []
@page_drop.children.my_method # Prints all the children

然后,您未在PageArray中定义的任何函数都会落入Ruby Array方法。