2011-08-08 48 views
1

我錯過了一些愚蠢的東西。幫幫我?紅寶石(導軌) - 包括模型

的lib/api.rb

require 'httparty' 

module API 
    def self.call_api(query) 
    base_url = "http://myapi.com" 
    return HTTParty.get("#{base_url}/#{query}.json") 
    end 
end 

型號/ job.rb

require 'api' 

class Job 
    include API 

    def self.all(page=1) 
    self.call_api "jobs?page=#{page}" 
    end 

end 

Job::all NoMethodError: undefined method `call_api' for Job:Class

如果我提出我的 「call_api」 直接進入作業類,它的工作原理。我錯過了什麼?

回答

2

其他的答案都指出你的問題,您應該延長,而不是包括:

class Job 
    extend API 

您也不妨考慮採用以下模式這除了是有用的也可以幫助緩解混亂,因爲你可以直接告訴你的類方法在ClassMethods模塊中,而你的實例方法直接在MyModule模塊中。

module MyModule 

    def self.included(base) 
    base.extend(ClassMethods) 
    end 

    module ClassMethods 
    def my_class_method 
    end 
    end 

    def my_instance_method 
    end 
end 

這將使用Ruby的included回調(這被激發每個時間包含在類模塊),我們重新定義回調(通常什麼都不做),以擴展該模塊是班上包含在ClassMethods子模塊中。這是Ruby中非常常見的元編程模式。如果你使用這種模式,你再也不用擔心擴展,只需使用include

class MyClass 
    include MyModule 

則:

MyClass.my_class_method 
MyClass.new.my_instance_method 

你也可以採取這種模式得遠一點:

module MyModule 
    include ClassMethods 

    def self.included(base) 
    base.extend(ClassMethods) 
    end 

    module ClassMethods 
    def my_class_method 
    end 
    end 

    def my_instance_method 
    end 
end 

請注意,父模塊直接包含其子模塊ClassMethods模塊。這樣my_class_method同時成爲一個實例和類方法:

class MyClass 
    include MyModule 

MyClass.my_class_method 
MyClass.new.my_class_method 

你,如果你做的是有點小心,你怎麼ClassMethods子模塊代碼的方法。但我偶然發現這種模式非常方便。

0

問題是您直接在API模塊上定義方法call_api,而不是在Job類的繼承鏈上。

您可以撥打API.call_api就好了,但問題是,API的「實例方法」不繼承鏈(所包含的模塊的接收器定義不是實例方法的一部分,但API的單實例的方法 - 記住API是類模塊的用自己的方法的實例)

這是做什麼你正在嘗試做的方式:

module API 
    def self.included(base) 
    def base.call_api(...) 
     ... 
    end 
    end 
end 

但也有可能使用extend而不是更簡潔的方式include你的類。