2008-09-24 115 views
77

我有一些控制器方法我想分享重用在Ruby中控制器之間的代碼。在軌道上做紅寶石的最佳做法是什麼?我應該創建一個我的控制器擴展的抽象類,還是應該創建模塊並將其添加到每個控制器中?以下是我想要分享的控制器方法:最佳實踐on Rails的

def driving_directions 
    @address_to = params[:address_to] 
    @address_from = params[:address_from] 
    @map_center = params[:map_center_start] 

    # if we were not given a center point to start our map on 
    # let's create one. 
    if [email protected]_center && @address_to 
    @map_center = GeoKit::Geocoders::MultiGeocoder.geocode(@address_to).ll 
    elsif [email protected]_center && @address_from 
    @map_center = GeoKit::Geocoders::MultiGeocoder.geocode(@address_from).ll 
    end 
end 

def printer_friendly 
    starting_point = params[:starting_point].split(',').collect{|e|e.to_f} 
    ne = params[:ne].split(',').collect{|e|e.to_f} 
    sw = params[:sw].split(',').collect{|e|e.to_f} 
    size = params[:size].split(',').collect{|e|e.to_f} 
    address = params[:address] 

    @markers = retrieve_points(ne,sw,size,false) 
    @map = initialize_map([[sw[0],sw[1]],[ne[0],ne[1]]],[starting_point[0],starting_point[1]],false,@markers,true) 
    @address_string = address 
end 
+1

在這種情況下是否有沒有使用application.rb的特殊原因? – 2008-09-24 19:07:07

+4

只有一些控制器會使用代碼,但不是全部。 – 2008-09-25 02:20:51

回答

110

在我看來,正常的面向對象的設計原則:

  • 如果代碼確實是一組不需要訪問對象狀態的實用工具,我會考慮把它在一個模塊中被調用分別。例如,如果代碼是所有映射實用程序,請創建一個模塊Maps,並訪問諸如:Maps::driving_directions的方法。
  • 如果代碼需要狀態並在每個控制器中使用或可以使用,請將代碼放在ApplicationController中。
  • 如果代碼需要狀態,並且在被緊密地和邏輯地相關的所有控制器的一個子集被使用(即,所有有關映射),則創建一個基類(class MapController < ApplicationController),並把該共享代碼那裏。
  • 如果代碼需要國家,並在沒有很密切的關係的所有控制器的一個子集時,把它放在一個模塊中,並將其納入必要的控制器。

在你的情況下,方法需要狀態(params),所以選擇取決於需要它的控制器之間的邏輯關係。 此外:

另外:

  • 使用泛音時可能用於經由特定路徑重複的代碼和在一個共同的「諧音」目錄兩個地方或包括。
  • 堅持一個RESTful方法在可能的情況(對於方法),如果你發現自己創造了很多的非RESTful方法考慮他們提取到自己的控制器。
15

我實際上認爲模塊是在控制器之間共享代碼的最佳方式。如果你想在視圖中分享代碼,助手很好。助手基本上是榮耀的模塊,所以如果你不需要視圖級別的訪問,我建議在你的lib文件夾中放置一個模塊。

一旦你創建的模塊,你就必須使用include語句包括在所需的控制器。

http://www.rubyist.net/~slagell/ruby/modules.html

1

我同意模塊的方法。在lib目錄下創建一個單獨的Ruby文件,並將該模塊放入新文件中。

最明顯的方法是將方法添加到您的ApplicationController,但我相信你已經知道了。

0

另一種可能性:

如果您共同的代碼需要國家,你想分享的控制器之間的行爲,你可以把它放在你的任何或model目錄lib一個普通的老Ruby類。請記住,即使所有ActiveRecord類都是持久的,類也不一定是持久的。換句話說,可以接受有暫態的model類。

1

如果你想在控制器和助手之間共享代碼,那麼你應該嘗試在庫中創建一個模塊。您可以使用@template和@controller來訪問controller和helper中的方法。 檢查此瞭解更多詳情http://www.shanison.com/?p=305

29

我知道這個問題6年前有人問。只是想指出,在Rails 4中,現在有了Controller Concerns,這是一個更加現成的解決方案。

0

我發現跨控制器共享相同代碼的一種有效方法是讓一個控制器從另一個控制器(代碼所在的地方)繼承。我使用這種方法將我的控制器中定義的相同方法與另一組名稱空間控制器共享。