1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00
rails--rails/activeresource/lib/active_resource/base.rb

156 lines
4 KiB
Ruby

require 'active_resource/connection'
module ActiveResource
class Base
class << self
attr_reader :site
def site=(site)
@site = site.is_a?(URI) ? site : URI.parse(site)
end
def connection(refresh = false)
@connection = Connection.new(site) if refresh || @connection.nil?
@connection
end
def element_name
self.to_s.underscore
end
def collection_name
element_name.pluralize
end
def prefix(options={})
default = site.path
default << '/' unless default[-1..-1] == '/'
set_prefix default
prefix(options)
end
def set_prefix(value = '/')
prefix_call = value.gsub(/:\w+/) { |s| "\#{options[#{s}]}" }
method_decl = %(def self.prefix(options={}) "#{prefix_call}" end)
eval method_decl
end
def set_element_name(value)
class << self ; attr_reader :element_name ; end
@element_name = value
end
def set_collection_name(value)
class << self ; attr_reader :collection_name ; end
@collection_name = value
end
def element_path(id, options = {})
"#{prefix(options)}#{collection_name}/#{id}.xml"
end
def collection_path(options = {})
"#{prefix(options)}#{collection_name}.xml"
end
def primary_key
set_primary_key 'id'
end
def set_primary_key(value)
class << self ; attr_reader :primary_key ; end
@primary_key = value
end
# Person.find(1) # => GET /people/1.xml
# StreetAddress.find(1, :person_id => 1) # => GET /people/1/street_addresses/1.xml
def find(*arguments)
scope = arguments.slice!(0)
options = arguments.slice!(0) || {}
case scope
when :all then find_every(options)
when :first then find_every(options).first
else find_single(scope, options)
end
end
private
# { :people => { :person => [ person1, person2 ] } }
def find_every(options)
connection.get(collection_path(options)).values.first.values.first.collect { |element| new(element, options) }
end
# { :person => person1 }
def find_single(scope, options)
new(connection.get(element_path(scope, options)).values.first, options)
end
end
attr_accessor :attributes
attr_accessor :prefix_options
def initialize(attributes = {}, prefix_options = {})
@attributes = attributes
@prefix_options = prefix_options
end
def new_resource?
id.nil?
end
def id
attributes[self.class.primary_key]
end
def id=(id)
attributes[self.class.primary_key] = id
end
def save
new_resource? ? create : update
end
def destroy
connection.delete(self.class.element_path(id, prefix_options)[0..-5])
end
def to_xml
attributes.to_xml(:root => self.class.element_name)
end
# Reloads the attributes of this object from the remote web service.
def reload
@attributes.update(self.class.find(self.id, @prefix_options).instance_variable_get(:@attributes))
self
end
protected
def connection(refresh = false)
self.class.connection(refresh)
end
def update
connection.put(self.class.element_path(id, prefix_options)[0..-5], to_xml)
end
def create
returning connection.post(self.class.collection_path(prefix_options)[0..-5], to_xml) do |resp|
self.id = resp['Location'][/\/([^\/]*?)(\.\w+)?$/, 1]
end
end
def method_missing(method_symbol, *arguments)
method_name = method_symbol.to_s
case method_name.last
when "="
attributes[method_name.first(-1)] = arguments.first
when "?"
attributes[method_name.first(-1)] == true
else
attributes.has_key?(method_name) ? attributes[method_name] : super
end
end
end
end