2

在RefineryCMS gem中,有一個Page模型用於從CMS中獲取信息。該模型未在您的當前應用中定義,因此您無法修改其代碼(除非跳轉到寶石代碼中)。Rails 3 - 擴展存在於gem或插件中的模型

有沒有辦法修改現有模型中的方法,而無需在每次加載頁面時應用更改?這是我曾嘗試:

  1. Model.class_eval

  2. Model.send:包括MixinThatHasNewMethods

我也試過用更新的方法創建一個新的類,希望能夠更新現有的課程。

任何想法?

回答

4

Ruby允許開發人員隨時「更新」任何對象。

這意味着,Model由RefineryCMS加載後,你可以重新打開類更新:

class Model 
    def new_method(value) 
     ... 
    end 

    def existing_method(*args) 
     ... 
     super # refer to the ovewriten method 
    end 
end 

在你的情況RafineryCMS是一個RoR應用程序,這意味着在加載服務器的紅寶石代碼加載首先用於rails框架,然後用於RafineryCMS gem/plugin,最後用於您的自定義庫(例如:lib文件夾)。

這裏重要的一點是代碼的加載順序,修改應該在真正的類代碼之後加載。

這是在你的lib或initializers(不是一個很好的地方,但它的工作原理),你應該把你的custome方法爲Model類。

編輯:我再次讀你的問題,我不得不提到,你錯了,你實際上可以改變一個類從一個寶石或插件。 紅寶石加載同一範圍內的每個對象,並且所有對象都可以被覆蓋。

在開發環境RoR中,在每個請求上重新加載所有類(除非是cache_classes = false)。有可能,在第一次請求之後,寶石會重新加載並且您的更改將丟失。小心刷新你的庫後(僅在研究與開發ENV)每個請求

PS:包括& class_eval將工作太,最重要的是太多覆蓋先前加載的類

0

如果我正確理解你的問題,你可以做這樣的事情。

您可以如下覆蓋模型。假設你有以下類:

class User 
def name user_name 
    p "my name is #{user_name}" 
end 

def age my_age 
    p "age - #{my_age}" 
end 

end 

,那麼你可以通過調用這個類:

user = User.new 
user.name "sameera" 
user.age 30 

,你會得到輸出:

"my name is sameera" 
"age - 30" 

然後說你只想改變'name'方法的行爲,您可以重新創建用戶類並僅添加該方法,如下所示:

class User 
def name user_name 
    p "my modified name #{user_name}" 
end 
end 

,仍然可以調用這兩種方法如下:

user = User.new 
user.name "sameera" 
user.age 30 

但是這一次,你的輸出將是:

"my modified name sameera" 
"age - 30" 

我覺得你有我的觀點,希望這有助於。

**注意:在加載原始User類之前,請確保調用修改的'User'類。