zendesk_api 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +7 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/.yardopts +1 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +59 -0
- data/LICENSE +19 -0
- data/Rakefile +49 -0
- data/Readme.md +178 -0
- data/lib/zendesk_api.rb +10 -0
- data/lib/zendesk_api/actions.rb +176 -0
- data/lib/zendesk_api/association.rb +267 -0
- data/lib/zendesk_api/client.rb +150 -0
- data/lib/zendesk_api/collection.rb +233 -0
- data/lib/zendesk_api/configuration.rb +52 -0
- data/lib/zendesk_api/core_ext/inflection.rb +13 -0
- data/lib/zendesk_api/core_ext/modulize.rb +10 -0
- data/lib/zendesk_api/core_ext/snakecase.rb +12 -0
- data/lib/zendesk_api/lru_cache.rb +38 -0
- data/lib/zendesk_api/middleware/request/etag_cache.rb +38 -0
- data/lib/zendesk_api/middleware/request/retry.rb +39 -0
- data/lib/zendesk_api/middleware/request/upload.rb +32 -0
- data/lib/zendesk_api/middleware/response/callback.rb +19 -0
- data/lib/zendesk_api/middleware/response/deflate.rb +18 -0
- data/lib/zendesk_api/middleware/response/gzip.rb +18 -0
- data/lib/zendesk_api/middleware/response/parse_iso_dates.rb +29 -0
- data/lib/zendesk_api/rescue.rb +44 -0
- data/lib/zendesk_api/resource.rb +133 -0
- data/lib/zendesk_api/resources/forum.rb +51 -0
- data/lib/zendesk_api/resources/misc.rb +66 -0
- data/lib/zendesk_api/resources/playlist.rb +64 -0
- data/lib/zendesk_api/resources/ticket.rb +76 -0
- data/lib/zendesk_api/resources/user.rb +44 -0
- data/lib/zendesk_api/track_changes.rb +72 -0
- data/lib/zendesk_api/trackie.rb +8 -0
- data/lib/zendesk_api/verbs.rb +43 -0
- data/lib/zendesk_api/version.rb +3 -0
- data/live/Readme.md +4 -0
- data/live/activity_spec.rb +5 -0
- data/live/audit_spec.rb +5 -0
- data/live/bookmark_spec.rb +11 -0
- data/live/category_spec.rb +12 -0
- data/live/collection_spec.rb +68 -0
- data/live/crm_spec.rb +11 -0
- data/live/custom_role_spec.rb +5 -0
- data/live/forum_spec.rb +14 -0
- data/live/forum_subscription_spec.rb +12 -0
- data/live/group_membership_spec.rb +18 -0
- data/live/group_spec.rb +14 -0
- data/live/identity_spec.rb +14 -0
- data/live/locale_spec.rb +11 -0
- data/live/macro_spec.rb +5 -0
- data/live/mobile_device_spec.rb +11 -0
- data/live/organization_spec.rb +12 -0
- data/live/satisfaction_rating_spec.rb +6 -0
- data/live/setting_spec.rb +5 -0
- data/live/suspended_ticket_spec.rb +8 -0
- data/live/ticket_field_spec.rb +12 -0
- data/live/ticket_metrics_spec.rb +6 -0
- data/live/ticket_spec.rb +88 -0
- data/live/topic_comment_spec.rb +13 -0
- data/live/topic_spec.rb +18 -0
- data/live/topic_subscription_spec.rb +12 -0
- data/live/topic_vote_spec.rb +13 -0
- data/live/upload_spec.rb +9 -0
- data/live/user_spec.rb +13 -0
- data/live/view_spec.rb +6 -0
- data/spec/association_spec.rb +210 -0
- data/spec/client_spec.rb +149 -0
- data/spec/collection_spec.rb +302 -0
- data/spec/configuration_spec.rb +24 -0
- data/spec/create_resource_spec.rb +39 -0
- data/spec/data_resource_spec.rb +229 -0
- data/spec/fixtures/Argentina.gif +0 -0
- data/spec/fixtures/Argentina2.gif +0 -0
- data/spec/fixtures/credentials.yml.example +3 -0
- data/spec/fixtures/test_resources.rb +8 -0
- data/spec/fixtures/zendesk.rb +88 -0
- data/spec/lru_cache_spec.rb +26 -0
- data/spec/macros/resource_macros.rb +157 -0
- data/spec/middleware/request/etag_cache_spec.rb +17 -0
- data/spec/middleware/request/retry_spec.rb +47 -0
- data/spec/middleware/request/test.jpg +0 -0
- data/spec/middleware/request/upload_spec.rb +74 -0
- data/spec/middleware/response/callback_spec.rb +17 -0
- data/spec/middleware/response/deflate_spec.rb +15 -0
- data/spec/middleware/response/gzip_spec.rb +19 -0
- data/spec/middleware/response/parse_iso_dates_spec.rb +44 -0
- data/spec/playlist_spec.rb +95 -0
- data/spec/read_resource_spec.rb +37 -0
- data/spec/rescue_spec.rb +94 -0
- data/spec/resource_spec.rb +332 -0
- data/spec/spec_helper.rb +120 -0
- data/spec/string_spec.rb +7 -0
- data/spec/trackie_spec.rb +39 -0
- data/zendesk_api.gemspec +38 -0
- metadata +364 -0
@@ -0,0 +1,52 @@
|
|
1
|
+
module ZendeskAPI
|
2
|
+
class Configuration
|
3
|
+
# @return [String] The basic auth username.
|
4
|
+
attr_accessor :username
|
5
|
+
|
6
|
+
# @return [String] The basic auth password.
|
7
|
+
attr_accessor :password
|
8
|
+
|
9
|
+
# @return [String] The API url. Must be https unless {#allow_http} is set.
|
10
|
+
attr_accessor :url
|
11
|
+
|
12
|
+
# @return [Boolean] Whether to attempt to retry when rate-limited (http status: 429).
|
13
|
+
attr_accessor :retry
|
14
|
+
|
15
|
+
# @return [Logger] Logger to use when logging requests.
|
16
|
+
attr_accessor :logger
|
17
|
+
|
18
|
+
# @return [Hash] Client configurations (eg ssh config) to pass to Faraday
|
19
|
+
attr_accessor :client_options
|
20
|
+
|
21
|
+
# @return [Symbol] Faraday adapter
|
22
|
+
attr_accessor :adapter
|
23
|
+
|
24
|
+
# @return [Boolean] Whether to allow non-HTTPS connections for development purposes.
|
25
|
+
attr_accessor :allow_http
|
26
|
+
|
27
|
+
# Use this cache instead of default ZendeskAPI::LRUCache.new
|
28
|
+
# - must respond to read/write/fetch e.g. ActiveSupport::Cache::MemoryStore.new)
|
29
|
+
# - pass false to disable caching
|
30
|
+
# @return [ZendeskAPI::LRUCache]
|
31
|
+
attr_accessor :cache
|
32
|
+
|
33
|
+
def initialize
|
34
|
+
@client_options = {}
|
35
|
+
self.cache = ZendeskAPI::LRUCache.new(1000)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Sets accept and user_agent headers, and url.
|
39
|
+
#
|
40
|
+
# @return [Hash] Faraday-formatted hash of options.
|
41
|
+
def options
|
42
|
+
{
|
43
|
+
:headers => {
|
44
|
+
:accept => 'application/json',
|
45
|
+
:accept_encoding => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
|
46
|
+
:user_agent => "ZendeskAPI API #{ZendeskAPI::VERSION}"
|
47
|
+
},
|
48
|
+
:url => @url
|
49
|
+
}.merge(client_options)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# From https://github.com/rubyworks/facets/blob/master/lib/core/facets/string/modulize.rb
|
2
|
+
class String
|
3
|
+
def modulize
|
4
|
+
#gsub('__','/'). # why was this ever here?
|
5
|
+
gsub(/__(.?)/){ "::#{$1.upcase}" }.
|
6
|
+
gsub(/\/(.?)/){ "::#{$1.upcase}" }.
|
7
|
+
gsub(/(?:_+|-+)([a-z])/){ $1.upcase }.
|
8
|
+
gsub(/(\A|\s)([a-z])/){ $1 + $2.upcase }
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# From https://github.com/rubyworks/facets/blob/master/lib/core/facets/string/snakecase.rb
|
2
|
+
class String
|
3
|
+
def snakecase
|
4
|
+
#gsub(/::/, '/').
|
5
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
6
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
7
|
+
tr('-', '_').
|
8
|
+
gsub(/\s/, '_').
|
9
|
+
gsub(/__+/, '_').
|
10
|
+
downcase
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module ZendeskAPI
|
2
|
+
# http://codesnippets.joyent.com/posts/show/12329
|
3
|
+
class ZendeskAPI::LRUCache
|
4
|
+
attr_accessor :size
|
5
|
+
|
6
|
+
def initialize(size = 10)
|
7
|
+
@size = size
|
8
|
+
@store = {}
|
9
|
+
@lru = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def write(key, value)
|
13
|
+
@store[key] = value
|
14
|
+
set_lru(key)
|
15
|
+
@store.delete(@lru.pop) if @lru.size > @size
|
16
|
+
value
|
17
|
+
end
|
18
|
+
|
19
|
+
def read(key)
|
20
|
+
set_lru(key)
|
21
|
+
@store[key]
|
22
|
+
end
|
23
|
+
|
24
|
+
def fetch(key)
|
25
|
+
if @store.has_key? key
|
26
|
+
read key
|
27
|
+
else
|
28
|
+
write key, yield
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def set_lru(key)
|
35
|
+
@lru.unshift(@lru.delete(key) || key)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "faraday/middleware"
|
2
|
+
|
3
|
+
module ZendeskAPI
|
4
|
+
module Middleware
|
5
|
+
module Request
|
6
|
+
# Request middleware that caches responses based on etags
|
7
|
+
# can be removed once this is merged: https://github.com/pengwynn/faraday_middleware/pull/42
|
8
|
+
class EtagCache < Faraday::Middleware
|
9
|
+
def initialize(app, options = {})
|
10
|
+
@app = app
|
11
|
+
@cache = options[:cache] ||
|
12
|
+
raise("need :cache option e.g. ActiveSupport::Cache::MemoryStore.new")
|
13
|
+
@cache_key_prefix = options.fetch(:cache_key_prefix, :faraday_etags)
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(env)
|
17
|
+
return @app.call(env) unless [:get, :head].include?(env[:method])
|
18
|
+
cache_key = [@cache_key_prefix, env[:url].to_s]
|
19
|
+
|
20
|
+
# send known etag
|
21
|
+
if cached = @cache.read(cache_key)
|
22
|
+
env[:request_headers]["If-None-Match"] ||= cached[:response_headers]["Etag"]
|
23
|
+
end
|
24
|
+
|
25
|
+
@app.call(env).on_complete do
|
26
|
+
if cached && env[:status] == 304 # not modified
|
27
|
+
env[:body] = cached[:body]
|
28
|
+
end
|
29
|
+
|
30
|
+
if env[:status] == 200 && env[:response_headers]["Etag"] # modified and cacheable
|
31
|
+
@cache.write(cache_key, env)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require "faraday/middleware"
|
2
|
+
|
3
|
+
module ZendeskAPI
|
4
|
+
module Middleware
|
5
|
+
module Request
|
6
|
+
# Faraday middleware to handle HTTP Status 429 (rate limiting) / 503 (maintenance)
|
7
|
+
class Retry < Faraday::Middleware
|
8
|
+
DEFAULT_RETRY_AFTER = 10
|
9
|
+
ERROR_CODES = [429, 503]
|
10
|
+
|
11
|
+
def initialize(app, options={})
|
12
|
+
super(app)
|
13
|
+
@logger = options[:logger]
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(env)
|
17
|
+
response = @app.call(env)
|
18
|
+
|
19
|
+
if ERROR_CODES.include?(response.env[:status])
|
20
|
+
seconds_left = (response.env[:response_headers][:retry_after] || DEFAULT_RETRY_AFTER).to_i
|
21
|
+
@logger.warn "You have been rate limited. Retrying in #{seconds_left} seconds..." if @logger
|
22
|
+
|
23
|
+
seconds_left.times do |i|
|
24
|
+
sleep 1
|
25
|
+
time_left = seconds_left - i
|
26
|
+
@logger.warn "#{time_left}..." if time_left > 0 && time_left % 5 == 0 && @logger
|
27
|
+
end
|
28
|
+
|
29
|
+
@logger.warn "" if @logger
|
30
|
+
|
31
|
+
@app.call(env)
|
32
|
+
else
|
33
|
+
response
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "faraday/middleware"
|
2
|
+
require "mime/types"
|
3
|
+
|
4
|
+
module ZendeskAPI
|
5
|
+
module Middleware
|
6
|
+
module Request
|
7
|
+
class Upload < Faraday::Middleware
|
8
|
+
def call(env)
|
9
|
+
if env[:body] && env[:body][:file]
|
10
|
+
file = env[:body].delete(:file)
|
11
|
+
case file
|
12
|
+
when File
|
13
|
+
path = file.path
|
14
|
+
when String
|
15
|
+
path = file
|
16
|
+
else
|
17
|
+
warn "WARNING: Passed invalid filename #{file} of type #{file.class} to upload"
|
18
|
+
end
|
19
|
+
|
20
|
+
if path
|
21
|
+
env[:body][:filename] ||= File.basename(path)
|
22
|
+
mime_type = MIME::Types.type_for(path).first || "application/octet-stream"
|
23
|
+
env[:body][:uploaded_data] = Faraday::UploadIO.new(path, mime_type)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
@app.call(env)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require "faraday/response"
|
2
|
+
|
3
|
+
module ZendeskAPI
|
4
|
+
module Middleware
|
5
|
+
module Response
|
6
|
+
class Callback < Faraday::Response::Middleware
|
7
|
+
def initialize(app, client)
|
8
|
+
super(app)
|
9
|
+
@client = client
|
10
|
+
end
|
11
|
+
|
12
|
+
def on_complete(env)
|
13
|
+
super(env)
|
14
|
+
@client.callbacks.each {|c| c.call(env)}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'faraday_middleware/response_middleware'
|
2
|
+
|
3
|
+
module ZendeskAPI
|
4
|
+
module Middleware
|
5
|
+
module Response
|
6
|
+
# Faraday middleware to handle content-encoding = inflate
|
7
|
+
class Deflate < FaradayMiddleware::ResponseMiddleware
|
8
|
+
define_parser do |body|
|
9
|
+
Zlib::Inflate.inflate(body)
|
10
|
+
end
|
11
|
+
|
12
|
+
def parse_response?(env)
|
13
|
+
super && env[:response_headers]['content-encoding'] == "deflate"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'faraday_middleware/response_middleware'
|
2
|
+
|
3
|
+
module ZendeskAPI
|
4
|
+
module Middleware
|
5
|
+
module Response
|
6
|
+
# Faraday middleware to handle content-encoding = gzip
|
7
|
+
class Gzip < FaradayMiddleware::ResponseMiddleware
|
8
|
+
define_parser do |body|
|
9
|
+
Zlib::GzipReader.new(StringIO.new(body)).read
|
10
|
+
end
|
11
|
+
|
12
|
+
def parse_response?(env)
|
13
|
+
super && env[:response_headers]['content-encoding'] == "gzip"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'time'
|
2
|
+
require "faraday/response"
|
3
|
+
|
4
|
+
module ZendeskAPI
|
5
|
+
module Middleware
|
6
|
+
module Response
|
7
|
+
# Parse ISO dates from response body
|
8
|
+
class ParseIsoDates < Faraday::Response::Middleware
|
9
|
+
def call(env)
|
10
|
+
response = @app.call(env)
|
11
|
+
parse_dates! response.env[:body]
|
12
|
+
response
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def parse_dates!(value)
|
18
|
+
case value
|
19
|
+
when Hash then value.each { |key,element| value[key] = parse_dates!(element) }
|
20
|
+
when Array then value.each_with_index { |element, index| value[index] = parse_dates!(element) }
|
21
|
+
when /\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z\Z/m then Time.parse(value)
|
22
|
+
else
|
23
|
+
value
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module ZendeskAPI
|
2
|
+
module Rescue
|
3
|
+
def self.included(klass)
|
4
|
+
klass.extend(Methods)
|
5
|
+
klass.send(:include, Methods)
|
6
|
+
end
|
7
|
+
|
8
|
+
module Methods
|
9
|
+
def log_error(e, method = false)
|
10
|
+
if logger = (@client ? @client.config.logger : Kernel)
|
11
|
+
logger.warn "#{self} - #{method}" if method
|
12
|
+
logger.warn e.message
|
13
|
+
logger.warn e.backtrace.join("\n")
|
14
|
+
logger.warn "\t#{e.response[:body].inspect}" if e.response
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def rescue_client_error(*args)
|
19
|
+
opts = args.last.is_a?(Hash) ? args.pop : {}
|
20
|
+
|
21
|
+
if args.any?
|
22
|
+
args.each do |method|
|
23
|
+
class_eval("alias :orig_#{method} :#{method}")
|
24
|
+
define_method method do |*args|
|
25
|
+
begin
|
26
|
+
send("orig_#{method}", *args)
|
27
|
+
rescue Faraday::Error::ClientError => e
|
28
|
+
log_error(e, method)
|
29
|
+
opts[:with].respond_to?(:call) ? opts[:with].call : opts[:with]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
elsif block_given?
|
34
|
+
begin
|
35
|
+
yield
|
36
|
+
rescue Faraday::Error::ClientError => e
|
37
|
+
log_error(e)
|
38
|
+
opts[:with].respond_to?(:call) ? opts[:with].call : opts[:with]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'zendesk_api/trackie'
|
2
|
+
require 'zendesk_api/actions'
|
3
|
+
require 'zendesk_api/association'
|
4
|
+
require 'zendesk_api/verbs'
|
5
|
+
|
6
|
+
module ZendeskAPI
|
7
|
+
# Represents a resource that only holds data.
|
8
|
+
class Data
|
9
|
+
include Associations
|
10
|
+
include Rescue
|
11
|
+
|
12
|
+
class << self
|
13
|
+
# The singular resource name taken from the class name (e.g. ZendeskAPI::Ticket -> ticket)
|
14
|
+
def singular_resource_name
|
15
|
+
@singular_resource_name ||= to_s.split("::").last.snakecase
|
16
|
+
end
|
17
|
+
|
18
|
+
# The resource name taken from the class name (e.g. ZendeskAPI::Ticket -> tickets)
|
19
|
+
def resource_name
|
20
|
+
@resource_name ||= singular_resource_name.plural
|
21
|
+
end
|
22
|
+
|
23
|
+
alias :model_key :resource_name
|
24
|
+
|
25
|
+
# Rails tries to load dependencies, which messes up automatic resource our own loading
|
26
|
+
if method_defined?(:const_missing_without_dependencies)
|
27
|
+
alias :const_missing :const_missing_without_dependencies
|
28
|
+
end
|
29
|
+
|
30
|
+
def only_send_unnested_params
|
31
|
+
@unnested_params = true
|
32
|
+
end
|
33
|
+
|
34
|
+
def unnested_params
|
35
|
+
@unnested_params ||= false
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# @return [Hash] The resource's attributes
|
40
|
+
attr_reader :attributes
|
41
|
+
# @return [ZendeskAPI::Association] The association
|
42
|
+
attr_accessor :association
|
43
|
+
|
44
|
+
# Create a new resource instance.
|
45
|
+
# @param [Client] client The client to use
|
46
|
+
# @param [Hash] attributes The optional attributes that describe the resource
|
47
|
+
def initialize(client, attributes = {})
|
48
|
+
raise "Expected a Hash for attributes, got #{attributes.inspect}" unless attributes.is_a?(Hash)
|
49
|
+
@association = attributes.delete(:association) || Association.new(:class => self.class)
|
50
|
+
@client = client
|
51
|
+
@attributes = ZendeskAPI::Trackie.new(attributes)
|
52
|
+
ZendeskAPI::Client.check_deprecated_namespace_usage @attributes, self.class.singular_resource_name
|
53
|
+
|
54
|
+
@attributes.clear_changes unless new_record?
|
55
|
+
end
|
56
|
+
|
57
|
+
# Passes the method onto the attributes hash.
|
58
|
+
# If the attributes are nested (e.g. { :tickets => { :id => 1 } }), passes the method onto the nested hash.
|
59
|
+
def method_missing(*args, &block)
|
60
|
+
raise NoMethodError, ":save is not defined" if args.first.to_sym == :save
|
61
|
+
@attributes.send(*args, &block)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Returns the resource id of the object or nil
|
65
|
+
def id
|
66
|
+
key?(:id) ? method_missing(:id) : nil
|
67
|
+
end
|
68
|
+
|
69
|
+
# Has this been object been created server-side? Does this by checking for an id.
|
70
|
+
def new_record?
|
71
|
+
id.nil?
|
72
|
+
end
|
73
|
+
|
74
|
+
# Returns the path to the resource
|
75
|
+
def path(*args)
|
76
|
+
@association.generate_path(self, *args)
|
77
|
+
end
|
78
|
+
|
79
|
+
def to_s
|
80
|
+
"#{self.class.singular_resource_name}: #{attributes.inspect}"
|
81
|
+
end
|
82
|
+
alias :inspect :to_s
|
83
|
+
|
84
|
+
def ==(other)
|
85
|
+
warn "Trying to compare #{other.class} to a Resource" if other && !other.is_a?(Data)
|
86
|
+
other.is_a?(self.class) && ((other.id && other.id == id) || (other.object_id == self.object_id))
|
87
|
+
end
|
88
|
+
alias :eql :==
|
89
|
+
alias :hash :id
|
90
|
+
|
91
|
+
def inspect
|
92
|
+
"#<#{self.class.name} #{@attributes.to_hash.inspect}>"
|
93
|
+
end
|
94
|
+
|
95
|
+
alias :to_param :attributes
|
96
|
+
end
|
97
|
+
|
98
|
+
# Indexable resource
|
99
|
+
class DataResource < Data
|
100
|
+
extend Verbs
|
101
|
+
end
|
102
|
+
|
103
|
+
# Represents a resource that can only GET
|
104
|
+
class ReadResource < DataResource
|
105
|
+
extend Read
|
106
|
+
end
|
107
|
+
|
108
|
+
# Represents a resource that can only POST
|
109
|
+
class CreateResource < DataResource
|
110
|
+
include Create
|
111
|
+
end
|
112
|
+
|
113
|
+
# Represents a resource that can only PUT
|
114
|
+
class UpdateResource < DataResource
|
115
|
+
include Update
|
116
|
+
end
|
117
|
+
|
118
|
+
# Represents a resource that can only DELETE
|
119
|
+
class DeleteResource < DataResource
|
120
|
+
include Destroy
|
121
|
+
end
|
122
|
+
|
123
|
+
# Represents a resource that can CRUD (create, read, update, delete).
|
124
|
+
class Resource < DataResource
|
125
|
+
extend Read
|
126
|
+
include Create
|
127
|
+
|
128
|
+
include Update
|
129
|
+
include Destroy
|
130
|
+
end
|
131
|
+
|
132
|
+
class SingularResource < Resource; end
|
133
|
+
end
|