2013-03-31 60 views
0

在我們的rails 3.2.12應用程序中,我們想要override methodinstance並使其返回空。理想情況下,我們可以在應用中爲每個model定義ONE generic overriding method如何在rails 3.2.12中覆蓋實例的方法?

例如,@projectProject模型的實例,而phone是列名稱。在方法覆蓋後,我們希望@project.phone在運行時返回空而不是列的值。如果應用中有另一款customer,我們可以做@customer.name並且收到零,假設@customercustomerinstance

我們覺得singleton classdefine_method可能有幫助。但我們不太明白他們將如何工作。有人可以解釋這個問題嗎?謝謝您的幫助。

+0

您是否試圖在視圖中隱藏電話號碼,或者您是否試圖從業務邏輯中隱藏這些實例具有這些特定屬性的事實? –

+0

我不確定實現該目標的最佳方式,但是您能告訴我們爲什麼需要此功能嗎?例如,是否阻止某些用戶訪問某些列? –

+0

是的,我們將在視圖中使用該方法。這個想法並沒有改變任何東西,並且仍然在使用,例如<%= @ project.phone%>。當@ project.phone被調用時,如果用戶訪問規則如此說明,覆蓋方法將會啓動並返回空。這與隱藏一個領域類似。 – user938363

回答

1

既然你說你只是想這樣做的意見,那麼它給我的印象是一個視圖助手將是值得考慮的:

# view.html.haml 
= value_for_view(:phone, @project) 

# application_helper.rb 
def value_for_view(attribute, object) 
    if overide_attributes_in_view? && object.respond_to?("#{attribute}_for_view") 
    object.send("#{attribute}_for_view") 
    else 
    object.send(attribute) 
    end 
end 

# application.rb 
def overide_attributes_in_view? 
    #do your stuff here to determine whether the original values should be shown or the 'overloads' 
end 

# project.rb 
def phone_for_view 
    nil # just add methods called "attribute_for_view" for whatever attributes you want to whatever models you want to have the attributes 'overloaded' (it's not really overloading, but it serves the purpose you describe) 
end 

或類似的...你可以修補AR :: Base的有一個「value_for_view」的方法,這樣的觀點看起來更像是這樣的:

# view.html.haml 
= @project.value_for_view(:phone) 

# monkey_patch_file.rb 
def value_for_view(attribute) 
    if respond_to?("#{attribute}_for_view") 
    send("#{attribute}_for_view") 
    else 
    send(attribute) 
    end 
end 

如果你堅持只要能夠調用@project.phone並獲得一個或其他值,就需要通過@project一個標誌來告訴它爲你做計算,因爲Rovermicroer的答案顯示(雖然,正如我所評論的,我不確定'超級'會起作用,但原則是正確的)。

3

忽略所有這些,額外的評論使這毫無價值。

而不是覆蓋一個實例方法,爲什麼不只是有一個實例變量,就像方法的開關一樣。

class Project < ActiveRecord::Base 

    def phone 
    if @do_not_call 
     nil 
    else 
     super 
    end 
    end 

    def do_not_call 
    @do_not_call = true 
    end 

    def do_call 
    @do_not_call = false 
    end 

end 

你會需要像慘慘

https://github.com/ryanb/cancan

使用的東西可以可以設定用戶的能力,做一些像下面這樣。

class Project < ActiveRecord::Base 

    def phone 
    if current_user can? :phone, self 
     super 
    else 
     nil 
    end 
    end 

end 
+0

該方法將用於視圖。該視圖將根據用戶訪問規則決定列是否應該爲空。這個想法並沒有改變任何東西。例如,如果用戶有權訪問電話,則<%= @ project.phone%>將返回電話號碼,如果不是基於用戶訪問規則,則返回空白。 – user938363

+0

然後,而不是如果@do_not_call,你可以做一些事情,如current_user && current_user.can_see_phone(this),其中can_see_phone將是一個用戶的方法,如果用戶有權訪問該項目上的電話號碼,將返回true。 – rovermicrover

+0

由於我們不知道哪個字段將是空的,除非我們爲模型中的每個字段定義了一個定義。有沒有一種方法我們只需要定義一次並在所有領域使用它? – user938363

1

一個覆蓋對象(實例)的方法的方法如下:

@project = Project.find(params[:id]) 
#@project.phone contains the database value 

def @project.phone 
    "" 
end 
#@project.phone returns an empty string now 
+0

有沒有一種方法可以定義一次方法,並通過添加對象實例來調用它?我們的應用中有很多模型。 – user938363

+0

對不起,我不太瞭解你的問題。你可以嘗試改寫它嗎?正如有人指出的,向實例添加方法是一種罕見的技術。您想從用戶的角度來實現什麼? –

+0

我們需要向rails視圖添加一些智能,以便在訪問規則如此時知道返回空。 – user938363