2008-11-28 30 views
2

我想驗證一個參數是Rails的一個特定的類的實例:Rails的:調用模型類在庫

def schedule(action, *args) 
    if arg.is_a? Aircraft 
    ... 
    end 
end 

我在一個庫班這樣做(文件是在lib/),我得到一個未初始化的恆定的飛機錯誤。飛機是一個模型類,與相應的aircraft.rb文件在應用程序/模型

我可以在庫中使用模型類和實例嗎?怎麼樣?


錯誤上下文:

在RSpec的測試發生的錯誤;該代碼在瀏覽器中運行。我試圖要求在_spec.rb文件中的模型,目前沒有成功。

回答

3

這會給你訪問到飛機模型:

require File.dirname(__FILE__) + "/../app/models/aircraft" 

[編輯]

丹尼爾帶來了有關上下文好點。如果您使用的是rake任務確保您加載的環境:

task :my_task => :environment do 
    # something happens... 
end 
4

您可以使用Rails的庫文件,模型類,你在完全正確的方式做這件事。提到時,Rails應該自動載入班級飛機。

所以我們需要更多的上下文來弄清楚它爲什麼會失敗。是否有可能在沒有Rails環境的情況下加載lib /文件?

解決此問題的一種方法是明確要求模型文件aircraft.rb。然而,你會發現這種方法很快就會導致瘋狂,因爲它會以微妙而令人驚訝的方式打破Rails自動加載器。如果您使用Rails類加載器,而不是針對它,Rails會更容易。

更新

所以,如果它在一個RSpec測試,可我們看到您正在使用加載在規範文件中的環境的代碼?它應該看起來像這樣:

require File.dirname(__FILE__) + '/../spec_helper' 

它需要位於文件的頂部。假設你已經安裝了RSpec Rails插件(here),並且你有RSpec插件的默認spec/spec_helper.rb文件。如果沒有這樣的文件,嘗試運行:

ruby script/generate rspec 
+0

啊,非常感謝!你指出了正確的方向:它在瀏覽器中運行得非常好。我沒有嘗試它,因爲我在做TDD:它在RSpec中斷。我會修改這個問題。 – 2008-11-29 13:37:50

0

不得不嘗試這一個: if arg.is_a? ::Aircraft

1

Daniel的答案是正確的,但請考慮:爲什麼庫類引用模型類?庫代碼不應該知道實際的模型類,儘管它可能知道它們提供的接口。

另一個考慮:爲什麼#schedule方法要求模型的類?如果一個新的模型類Spaceship想與#schedule一起工作,那麼#schedule將不得不改變以與它一起工作。這沒有必要。

相反,Aircraft對象與其他類的對象被#schedule對待的方式有什麼不同?你能否將這種差異提取到它自己的方法中?然後你可以將這些實現移到每個模型類中,並決定多態使用哪一個,而不是分支。

例如,曾經被認爲是:

def schedule(action, vehicle) 
    if vehicle.is_an?(Aircraft) 
    possible_days = case action 
    when "travel" 
     ["Mon", "Wed", "Fri"] 
    when "repair" 
     ["Sat", "Sun"] 
    end 
    possible_days.rand 
    elsif vehicle.is_a?(Spaceship) 
    possible_days = case action 
    when "travel" 
     ["Sat", "Tue", "Thu"] 
    when "repair" 
     ["Sun", "Mon"] 
    end 
    possible_days.rand 
    end 
end 

將成爲:

def schedule(action, vehicle) 
    vehicle.days_action_can_be_performed(action).rand 
end 


class Aircraft 
    def days_action_can_be_performed(action) 
    possible_days = case action 
    when "travel" 
     ["Mon", "Wed", "Fri"] 
    when "repair" 
     ["Sat", "Sun"] 
    end 
    possible_days 
    end 
end 

class Spaceship 
    def days_action_can_be_performed(action) 
    possible_days = case action 
    when "travel" 
     ["Sat", "Tue", "Thu"] 
    when "repair" 
     ["Sun", "Mon"] 
    end 
    possible_days 
    end 
end 

當添加一個新的類,它只是需要實現#days_action_can_be_performed,它會與#schedule工作。