lib/wordnik/resource.rb in wordnik-0.4.5 vs lib/wordnik/resource.rb in wordnik-0.4.6

- old
+ new

@@ -1,17 +1,22 @@ # To jog the memory: Resource > Endpoint > Operation > OperationParameter module Wordnik class Resource + require 'active_model' include ActiveModel::Validations include ActiveModel::Conversion extend ActiveModel::Naming attr_accessor :name, :raw_data, :endpoints, :models validates_presence_of :name, :raw_data, :endpoints, :models + + class << self + public :define_method + end def initialize(attributes = {}) attributes.each do |name, value| send("#{name.to_s.underscore.to_sym}=", value) end @@ -19,84 +24,18 @@ # Generate Endpoint instances from JSON if self.raw_data['endPoints'] self.endpoints = self.raw_data['endPoints'].map do |endpointData| Endpoint.new(self, endpointData) end - end - end - - # Cycle through endpoints and their operations in search of - # the path that corresponds to the given nickname - def path_for_operation_nickname(nickname) - self.endpoints.each do |endpoint| - endpoint.operations.each do |operation| - return endpoint.path if operation.nickname == nickname - end - end - nil - end - - # Uses the received method name and arguments to dynamically construct a Request - # If the method name is prefixed with 'build_', then the 'unmade' Request - # object will be returned instead of the Request Response's body - # - # Wordnik.word.get('dingo') - # Wordnik.word.get_definitions('dingo', :limit => 20, ) - def method_missing(sym, *args, &block) - nickname = sym.to_s - - # If method nickname starts with 'build_', - # then just build the request but don't run it. - if nickname =~ /^build_/ - nickname.gsub!('build_', '') - build_only = true - end + end - # Extrapolate HTTP method from beginning of method name - # e.g. 'post_words' -> :post - http_method = nickname.split("_").first.to_sym - - # Ruby turns all key-value arguments at the end into a single hash - # e.g. Wordnik.word.get_examples('dingo', :limit => 10, :part_of_speech => 'verb') - # becomes {:limit => 10, :part_of_speech => 'verb'} - last_arg = args.pop if args.last.is_a?(Hash) - last_arg = args.pop if args.last.is_a?(Array) - last_arg ||= {} - - if [:post, :put].include?(http_method) - params = nil - body = last_arg - else - params = last_arg - body = nil + # Attach module containing metaprogramatticaly generated operations. + module_filename = File.join(File.dirname(__FILE__), "./resource_modules/#{self.name}.rb") + if File.exist? module_filename + self.class.send(:require, "wordnik/resource_modules/#{self.name}") + self.class.send(:include, "#{self.name.to_s.camelize}Methods".constantize) end - # Find the path that corresponds to this method nickname - # e.g. post_words -> "/wordList.{format}/{wordListId}/words" - begin - path = self.path_for_operation_nickname(nickname) - rescue - raise "Cannot find a resource path that corresponds to the method nickname '#{nickname}'" - end - - # Take the '.{format}' portion out of the string so it doesn't interfere with - # the interpolation we're going to do on the path. - path.gsub!('.{format}', '') - - # Stick the remaining (required) arguments into the path string - args.each do |arg| - path.sub!(/\{\w+\}/, arg) - end - - # TODO: treat kwargs as body instead of params if request method is post or put - - request = Wordnik::Request.new(http_method, path, :params => params, :body => body) - - if build_only - request - else - request.response.body - end end # It's an ActiveModel thing.. def persisted? false \ No newline at end of file