Ruby on rails 这个Ruby类方法是如何被调用的?
在屏幕上,Ryan Bates展示了以下简单代码 我试图弄清楚类方法Product::to_csv实际上是如何在ProductController.rb的第5行被调用的,因为它似乎不遵循正常的Ruby规则 product.rbRuby on rails 这个Ruby类方法是如何被调用的?,ruby-on-rails,Ruby On Rails,在屏幕上,Ryan Bates展示了以下简单代码 我试图弄清楚类方法Product::to_csv实际上是如何在ProductController.rb的第5行被调用的,因为它似乎不遵循正常的Ruby规则 product.rb 1 class Product < ActiveRecord::Base 2 def self.to_csv(options = {}) 3 ... 4 end 5 end 1 class ProductsController < Ap
1 class Product < ActiveRecord::Base
2 def self.to_csv(options = {})
3 ...
4 end
5 end
1 class ProductsController < ApplicationController
2 def index
3 @products = Product.order(:name)
4 respond_to do |format|
5 format.csv { send_data @products.to_csv }
6 ...
7 end
8 end
9 end
1类产品
产品\u controller.rb
1 class Product < ActiveRecord::Base
2 def self.to_csv(options = {})
3 ...
4 end
5 end
1 class ProductsController < ApplicationController
2 def index
3 @products = Product.order(:name)
4 respond_to do |format|
5 format.csv { send_data @products.to_csv }
6 ...
7 end
8 end
9 end
1类产品控制器
由于to_csv是一个类方法,我希望调用看起来像Product::to_csv()
根据文档,@products是ActiveRecord::Relation的一个实例。为什么发送到ActiveRecord::Relation实例的消息会导致调用产品类对象上的方法?更奇怪的是,在发送方和接收方中,重命名为_csv为任意名称会导致NoMethodError,因此可能有一些基于以To_开头的名称的魔法正在酝酿中
我错过了什么明显的东西吗?如有任何澄清,将不胜感激。我现在可以回答以下问题: 为什么要将消息发送到ActiveRecord::Relation的实例 是否导致调用产品类对象上的方法
ActiveRecord::Relation
类用于链接多个方法,而不会实际触发多个SQL查询。通过这种方式,您可以编写类似于Product.where('price这只是Rails所做的事情之一。任何类方法都会自动成为“collection”方法,这意味着它们可用于关系对象。作用域和类方法可以通过这种方式互换。我了解ActiveRecord::relation的实例表示SQL查询的一部分或全部,对一个实例调用first或all会导致查询执行并创建一个数组(在本例中)类产品的实例。这并没有解释如何将to_csv消息发送到ActiveRecord::Relation的实例,从而导致类方法to_csv()被调用。谢谢,这可以解释这种行为。如果Rails指南或文档中有提到这一点就好了。根据您的回答,我查阅了源代码。如果我理解正确,ActiveRecord::Relations会将方法调用委托给相关的类对象(如果它响应它们),然后最终委托给:arelIf如果您有兴趣进一步探索这一点,我开始研究一个概念验证gem,它允许您将模型与集合分开。它被称为。我在生产中没有对它做太多工作,但您可以查看源代码,看看我必须做些什么才能在关系类上进行验证。我忘了提到ActiveRecord::Relations似乎还将方法委托给结果数组对象(必要时触发数据库获取)。它将首先在关联的ActiveRecord::Base上查找一个类方法,然后尝试数组,最后尝试:arel导致的任何结果。假设我在代码中找到了正确的位置。感谢您提供的信息。我一定会查看Herd。一些实验表明rails对all
的含义非常了解——因此,这类事情的行为正如人们对调用all
的类方法所期望的那样。如果能看到一些文档或代码来解释这种神奇行为是在什么情况下生效的,那就太好了。