为什么这个ruby方法没有在我的课程中定义?

时间:2014-05-30 02:50:30

标签: ruby

以下是代码:

module Dog
  class Breed < Animal::Base

    class << self
      def all
        get '/v1/breeds'
      end

      def find(hashed_id)
        get "/v1/breeds/#{breed_id}"
      end
    end

    def bark
      "woof"
    end
  end
end

对于基地:

module Dog
  class Base < ActiveRecord::Base
    include HTTParty

    base_uri 'https://api.dogs.com'
    format :json
    default_params api_password: ENV['ANIMAL_PASSWORD']
  end
end

module HTTParty
  module ClassMethods
    def get(path, options = {}, &block)
      response = perform_request(Net::HTTP::Get, path, options, &block)
      if response.is_a? Array
        methodize_array response
      elsif response.is_a? Hash
        new_ros response
      end
    end

    def methodize_array(response)
      array = []

      response.each do |res|
        array << new_ros(res)
      end

      array
    end

    private

    def new_ros(object)
      RecursiveOpenStruct.new(object, recurse_over_arrays: true)
    end
  end
end

这是一个愚蠢的例子,但它应该在理论上起作用。发生的是我们从API获取一些数据。当抓取数据时,我们发现它是一个哈希。我们不喜欢Hashes,所以我们在HTTParty中重新打开get请求并让它执行recursive open struct以使其成为对象。

我们执行此获取为Dog::Breed.all。我们收到一个阵列,感谢ROS,它被转换为一个对象。

现在,当我致电Dog::Breed.all.bark时,它无法正常工作:

undefined method `bark' for #<Array:0x007fc7acbb6108>

如果我成功:

def self.bark
  "woof"
end

然后拨打Dog::Breed.bark,它会对我不利。如何制作它以便我可以向Breed课程添加方法,以便我可以Dog::Breed.all.barkDog::Breed.find(2).bark

Dog::Breed.all的输出为#<RecursiveOpenStruct>。免责声明:这是一个例子,而非现实生活,dog.com导致了宠物智能。

1 个答案:

答案 0 :(得分:2)

Dog::Breed.all返回Array Breed,而非Breed。如果你想让所有的狗都吠叫你需要迭代阵列,并让每一只狗都吠叫:

Dog::Breed.all.each(&:bark)