代码之家  ›  专栏  ›  技术社区  ›  Ramon Tayag

ruby/rails:调用实例时是否可以执行默认方法(@instance==@instance.all,如果“all”是默认方法)?

  •  2
  • Ramon Tayag  · 技术社区  · 15 年前

    我知道我的问题有点含糊,但我不知道如何描述它。我问过很多地方,似乎没有人理解我为什么要这样做。但是请忍受我,我会解释为什么我要这样的东西。

    我正在使用液体模板允许用户在我的网站上创建一些动态页面。对于那些不知道的人,liquid使用他们的liquiddrop类向用户公开某些项目。液滴中的任何方法都可以由液体模板调用。

    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
    

    为了让我的用户更简单,我不希望他们考虑添加“全部”或不添加到drop实例,以获得它包含的“默认”对象。重申:

    @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.each,for person in@person.friends。

    2 回复  |  直到 15 年前
        1
  •  1
  •   mikej heading_to_tahiti    15 年前

    这是不可能的。当你写作时 @instance 你不是真的 调用实例 正如你所描述的,你得到了一个对象的引用 @实例 是指。

    它似乎与Rails关联的集合一起工作的原因是关联对象是 Array 它们的某些方法已被重写。

    我会考虑搬走 PagesDrop 并使用 group_by(&:method) 语法如果你想要一个简洁的方式来表达分组。如果您确实想保留它,那么您可以通过实现 each 和 [] 在 页面下降 让他们委托 @pages . 那会让你用 @page_drop.children 在里面 for 例如,循环。

        2
  •  0
  •   Jason Noble    15 年前

    看起来您要实现的Rails外部有很多。以下工作是否有效?

    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 # => []
    

    这还为您提供了所有标准数组函数(分组依据、大小、每个等)。如果要添加自己的方法,请创建一个继承自数组的类,并在其中添加方法。

    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数组方法中。