RoR的"神奇"命名空间解析如何工作?

Xiv*_*Xiv 3 ruby ruby-on-rails

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

1.任何地方都没有要求声明

在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
Run Code Online (Sandbox Code Playgroud)

记录器,重定向,以及这样的都没有定义.它是简单地从ApplicationController继承了一些复杂的树,还是以某种方式通过其他机制访问这些命名空间?

2.使用不存在的方法

这是有效的rails代码

current_item = line_items.find_by_product_id(product_id)
Run Code Online (Sandbox Code Playgroud)

其中find_by_products_id尚未在任何地方定义,但Rails以某种方式动态"创建"该方法.有关如何做到的任何技术见解?

谢谢你的帮助!

Mat*_*udy 9

Rails的"魔法"广泛使用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_missingparam "SomeModel"

遵循约定的Rails "SomeModel"应该在一个名为some_model.rb,const_missing只是尝试的文件中定义require "some_model".