3

我来自使用 Python,我对 Ruby on Rails 的“魔力”如何工作感到非常困惑。

1. 任何地方都没有 require 语句

在 Python 中,为了从任何地方访问函数,您必须导入。我认为基础红宝石也是如此。但是在使用 rails 时,我可以调用隐藏在其他模块中定义的变量和函数,而无需页面顶部的任何 require 语句。

例如,我可以有这样的文件:

class CartsController < ApplicationController
....
def show
        begin
            @cart = Cart.find(params[:id])
        rescue ActiveRecord::RecordNotFound
            logger.error "Attempt to access invalid cart #{params[:id]}"
            redirect_to store_url, notice: 'Invalid cart'
        end
 end

其中loggerredirect等都没有定义。它是简单地从 ApplicationController 继承一些复杂的树,还是通过其他机制以某种方式访问​​这些命名空间?

2.使用不存在的方法

这是有效的 Rails 代码

current_item = line_items.find_by_product_id(product_id)

find_by_products_id尚未在任何地方定义的地方,Rails 以某种方式动态地动态“创建”该方法。关于如何做到这一点的任何技术见解?

谢谢你的帮助!

4

3 回答 3

9

Rails 的“Magic”广泛使用method_missingconst_missing

当您尝试调用未定义的方法时,ruby 会触发对method_missing. 这被库ActiveRecord用来实现动态查找器。

method_missing 示例:

SomeModel.find_by_some_field("some_value")没有定义。

这调用SomeModel.method_missing(:find_by_some_field, "some_value").

ActiveRecord 然后将此调用转换为 `SomeModel.where(:some_field => "some_value")

(为了性能,ActiveRecord然后动态定义了这个方法,所以下次find_by_some_field定义)

const_missing 示例:

SomeModel尚未被要求。

Ruby 解释器const_missing使用参数"SomeModel"

Rails 遵循约定"SomeModel"应该在一个名为some_model.rbsoconst_missing的文件中定义require "some_model"

于 2013-01-17T20:54:14.573 回答
0

由于现有的答案都没有提到它:是的,像这样redirect_to的东西是通过 ApplicationController 继承的。在这种特殊情况下,在模块ActionController::Redirectingredirect_to中定义,该模块包含在 ActionController::Base 中(ApplicationController 继承自该模块)。

于 2013-01-17T21:43:28.783 回答
0

好的。你一口气问了很多问题。很难在一个答案中解释所有 ruby​​ 和 rails 魔法,但我会尝试为您提供一些有用的资源,您可以在其中找到一些答案。

1)关于require语句。如果您是 ruby​​ 和 rails 的新手,那么将很难理解 rails 应用程序是如何初始化的。这是一个教程,您可以获得一些有用的信息: http:
//guides.rubyonrails.org/initialization.html
如果您需要有关特定方法的更多信息,您可以随时查看文档。例如 redirect_to 方法信息:
http ://apidock.com/rails/ActionController/Base/redirect_to

2)关于“使用不存在的方法”。这是 ruby​​ 语言最漂亮的特性之一,称为元编程。这也是高级话题。以下是一些有用的资源:
http :
//www.amazon.com/Metaprogramming-Ruby-Program-Like-Pros/dp/1934356476 Ruby 元编程在线教程
http://yehudakatz.com/2009/11/15/metaprogramming-in -ruby-its-all-about-the-self/
http://rubylearning.com/blog/2010/11/23/dont-know-metaprogramming-in-ruby/

于 2013-01-17T21:05:45.580 回答