Here's the code:
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
And for the base:
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
This is a silly example, but it should work in theory. What happens is is that we grab some data from an API. When that data is grabbed, we discover that its a Hash. We don't like Hashes, so we reopen the get request within HTTParty and have it perform a recursive open struct to make it an object.
We perform this get as Dog::Breed.all
. We receive an array that, thankfully to ROS, was converted to an object.
Now, when I call Dog::Breed.all.bark
it doesn't work:
undefined method `bark' for #<Array:0x007fc7acbb6108>
If I make it:
def self.bark
"woof"
end
And then call Dog::Breed.bark
, it will woof at me. How do I make it so that I can add methods to the Breed
class so that I can do Dog::Breed.all.bark
or Dog::Breed.find(2).bark
?
The output from Dog::Breed.all
was a #<RecursiveOpenStruct>
. Disclaimer: That was an example case, not real life, dog.com
leads to petsmart.
Dog::Breed.all
returns an Array
of Breed
, not Breed
. If you want all dogs to bark you need to iterate over the array, and make each one bark:
Dog::Breed.all.each(&:bark)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.