我来自使用Python,我对Ruby on Rails的“魔力”如何运作感到非常困惑。
1。在任何地方都没有任何需要声明
在Python中,为了从任何地方访问函数,您必须导入。我认为基础红宝石也是如此。但是当使用rails时,我可以调用其他模块中定义的隐藏变量和函数,而不需要在页面顶部使用任何require语句。
E.g。我可以有一个文件:
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
记录器,重定向,等等都没有定义。它只是从ApplicationController继承了一些复杂的树,还是以某种方式通过其他机制访问这些命名空间?
2。使用不存在的方法
这是有效的rails代码
current_item = line_items.find_by_product_id(product_id)
其中 find_by_products_id 尚未在任何地方定义,但Rails会以某种方式动态“创建”该方法。关于如何做到的任何技术见解?
感谢您的帮助!
答案 0 :(得分:9)
Rails'“Magic”广泛使用method_missing
和const_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 =&gt;“some_value”)
(出于性能目的,ActiveRecord然后动态定义此方法,因此下次定义find_by_some_field
时)
const_missing示例:
SomeModel
尚未被要求。
Ruby解释器使用参数const_missing
“
"SomeModel
遵循惯例的Rails "SomeModel"
应该在名为some_model.rb
的文件中定义,因此const_missing
只会尝试require "some_model"
。
答案 1 :(得分:0)
确定。你在其中一个问了很多问题。在一个答案中很难解释所有ruby和rails魔法,但我会尝试给你一些有用的资源,你可以找到一些答案。
1)关于要求声明。如果您不熟悉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 metaprogramming online tutorial
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/
答案 2 :(得分:0)
由于现有的答案都没有提到它:是的,redirect_to
之类的东西是通过ApplicationController继承的。在这种特殊情况下,redirect_to
在模块ActionController::Redirecting中定义,它包含在ActionController :: Base中(ApplicationController从中继承)。