module ActiveResource module Singleton extend ActiveSupport::Concern module ClassMethods attr_writer :singleton_name def singleton_name @singleton_name ||= model_name.element end # Gets the singleton path for the object. If the +query_options+ parameter is omitted, Rails # will split from the \prefix options. # # ==== Options # * +prefix_options+ - A \hash to add a \prefix to the request for nested URLs (e.g., :account_id => 19 # would yield a URL like /accounts/19/purchases.json). # # * +query_options+ - A \hash to add items to the query string for the request. # # ==== Examples # Weather.singleton_path # # => /weather.json # # class Inventory < ActiveResource::Base # self.site = "https://37s.sunrise.com" # self.prefix = "/products/:product_id/" # end # # Inventory.singleton_path(:product_id => 5) # # => /products/5/inventory.json # # Inventory.singleton_path({:product_id => 5}, {:sold => true}) # # => /products/5/inventory.json?sold=true # def singleton_path(prefix_options = {}, query_options = nil) check_prefix_options(prefix_options) prefix_options, query_options = split_options(prefix_options) if query_options.nil? "#{prefix(prefix_options)}#{singleton_name}#{format_extension}#{query_string(query_options)}" end # Core method for finding singleton resources. # # ==== Arguments # Takes a single argument of options # # ==== Options # * :params - Sets the query and \prefix (nested URL) parameters. # # ==== Examples # Weather.find # # => GET /weather.json # # Weather.find(:params => {:degrees => 'fahrenheit'}) # # => GET /weather.json?degrees=fahrenheit # # == Failure or missing data # A failure to find the requested object raises a ResourceNotFound exception. # # Inventory.find # # => raises ResourceNotFound def find(options={}) find_singleton(options) end private # Find singleton resource def find_singleton(options) prefix_options, query_options = split_options(options[:params]) path = singleton_path(prefix_options, query_options) resp = self.format.decode(self.connection.get(path, self.headers).body) instantiate_record(resp, {}) end end # Deletes the resource from the remote service. # # ==== Examples # weather = Weather.find # weather.destroy # Weather.find # 404 (Resource Not Found) def destroy connection.delete(singleton_path, self.class.headers) end protected # Update the resource on the remote service def update connection.put(singleton_path(prefix_options), encode, self.class.headers).tap do |response| load_attributes_from_response(response) end end # Create (i.e. \save to the remote service) the \new resource. def create connection.post(singleton_path, encode, self.class.headers).tap do |response| self.id = id_from_response(response) load_attributes_from_response(response) end end private def singleton_path(options = nil) self.class.singleton_path(options || prefix_options) end end end