【问题标题】:Class methods in Ruby on Rails 3 — I'm totally lost!Ruby on Rails 3 中的类方法——我完全迷失了!
【发布时间】:2012-09-07 00:47:40
【问题描述】:

后台here.

在上面的链接中,给出了下面的例子:

class << self
  def by_author(author)
    where(:author_id => author.id)
  end
end

除了这种语法对于像我这样的初学者来说是陌生的——我一直认为类方法是用 def self.my_class_method 定义的——我在哪里可以找到关于 Ruby on Rails 中类方法的文档? p>

据我所知,类方法总是在类本身 (MyClass.my_class_method) 上调用,但如果 R​​ails 中的类方法是可链接的,似乎这里肯定发生了其他事情!

编辑:

我想我对类方法的语法发表评论有点作弊。我真的在问 Rails 如何使 class 方法 可链接——我了解方法链接的工作原理,但不知道 Rails 如何允许您在不实际返回类的情况下链接 class 方法在链中的每个“链接”之后的对象本身。

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    Ruby 中的类方法实际上只是单例类的成员,class &lt;&lt; self 涉及直接打开单例类并将其添加到其中,无需在每个方法定义中声明它。

    这个article on Ruby singletons 解释得很好。

    就类方法可链接而言,这不是特定于类方法的东西,第二个方法调用只是在从第一个返回的对象上调用。例如:

    bar = foo.do_something.do_more
    

    相当于:

    tmp = foo.do_something
    bar = tmp.do_more
    

    在 Rails 中,这种可链接性最常用于构建 SQL 查询(例如,使用 whereorder 等)。这是因为这些方法中的每一个都返回一个ActiveRecord Relation

    原因

     foo.scoped.my_foo_class_method
    

    工作是因为ActiveRecord::Relation#method_missing 做了以下事情:

    elsif @klass.respond_to?(method)
      scoping { @klass.send(method, *args, &block) }
    

    检查 ActiveRecord 类是否响应调用的方法,如果是,则调用该方法。

    【讨论】:

    • @1AndrewMarshall +1 谢谢你的回答。我了解什么会使方法“可链接”;我不明白 Rails 如何采用类方法并使 it 可链接。
    • 那个领先的1很漂亮。
    • Ooohhhhhh 我想我明白你的意思了。您是否在问为什么特定于单个模型的命名范围可以与通常的 whereorder 等链接? (如果没有,请通过使用具体示例编辑您的问题来进一步澄清,谢谢。)
    • 我实际上不确定像User.order.by_author 这样的东西是否会起作用……尽管User.by_author.order 肯定会。
    • 确实如此。我最好的猜测是它使用了 Ruby 的 method_missing 来寻找模型类中的方法,但我必须深入研究代码才能确定。
    【解决方案2】:

    拥有 class def self.my_method1 结尾 def self.my_method2 结尾 类

    干杯!

    【讨论】:

      【解决方案3】:

      以下两位代码是等价的。

      使用self.method

      class Hello
        def self.world
          puts "Hello, World!"
        end
      end
      

      使用class &lt;&lt; self

      class Hello
        class << self
          def world
            puts "Hello, World!"
          end
        end
      end
      

      唯一的区别是可读性,以及重构的容易程度。 元编程时经常使用class &lt;&lt; self 技术。

      还有另一个线程可以解释这一点。 class << self vs self.method with Ruby: what's better?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多