2013-01-17 29 views
3

我來自使用Python,對於Ruby on Rails的「魔力」如何工作我感到非常困惑。RoR的「魔術」名稱空間解析如何工作?

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的某種方式動態地 「創造」 的方法方法。有關如何完成的任何技術洞察?

感謝您的幫助!

回答

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_missing與帕拉姆"SomeModel

Rails的如下公約"SomeModel"應該在一個文件中定義了一個名爲some_model.rb所以const_missing只是試圖require "some_model"

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 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/

0

因爲無論是現有的答案提到它:是的,像redirect_to被ApplicationController的方式繼承。在這種特殊情況下,在模塊ActionController::Redirecting中定義了redirect_to,該模塊包含在ActionController :: Base(ApplicationController從中繼承)中。