kelredd-resourceful 0.7.24 → 0.7.25
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/Rakefile +1 -0
- data/lib/resourceful.rb +1 -1
- data/lib/resourceful/agent/base.rb +59 -59
- data/lib/resourceful/agent/mechanize.rb +33 -33
- data/lib/resourceful/agent/rest_client.rb +47 -47
- data/lib/resourceful/exceptions.rb +20 -20
- data/lib/resourceful/extensions.rb +34 -182
- data/lib/resourceful/model/activerecord_associations.rb +77 -78
- data/lib/resourceful/model/attribute_types.rb +34 -35
- data/lib/resourceful/model/base.rb +164 -164
- data/lib/resourceful/model/embedded_associations.rb +56 -57
- data/lib/resourceful/model/external_associations.rb +77 -78
- data/lib/resourceful/model/findable.rb +93 -94
- data/lib/resourceful/model/json.rb +62 -62
- data/lib/resourceful/model/xml.rb +70 -70
- data/lib/resourceful/resource/cache.rb +37 -42
- data/lib/resourceful/resource/format.rb +43 -47
- data/lib/resourceful/shoulda/test_unit.rb +90 -112
- data/lib/resourceful/version.rb +1 -1
- metadata +12 -2
data/Rakefile
CHANGED
data/lib/resourceful.rb
CHANGED
@@ -1,73 +1,73 @@
|
|
1
1
|
require 'log4r'
|
2
2
|
require "resourceful/resource/cache"
|
3
3
|
|
4
|
-
module Resourceful
|
5
|
-
module Agent
|
6
|
-
class Base
|
7
|
-
|
8
|
-
attr_reader :logger, :cache, :expiration, :log_prefix
|
4
|
+
module Resourceful; end
|
9
5
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
ATTRS.each { |a| instance_variable_set("@#{a.to_s}", args.delete(a)) }
|
15
|
-
@cache = Resourceful::Resource::Cache.new @expiration
|
16
|
-
@logger = Log4r::Logger.new('[Resourceful]')
|
17
|
-
@logger.add(Log4r::StdoutOutputter.new('console'))
|
18
|
-
end
|
19
|
-
|
20
|
-
protected
|
6
|
+
module Resourceful::Agent
|
7
|
+
class Base
|
8
|
+
|
9
|
+
attr_reader :logger, :cache, :expiration, :log_prefix
|
21
10
|
|
22
|
-
|
23
|
-
|
24
|
-
format = Resourceful::Resource::Format.get(opts[:format])
|
25
|
-
|
26
|
-
full_resource_path = self.class.resource_path(path, format, opts[:params])
|
27
|
-
resource_summary = summary(verb.to_s, full_resource_path)
|
28
|
-
cache_key = Resourceful::Resource::Cache.key(@host, verb.to_s, full_resource_path)
|
29
|
-
|
30
|
-
if opts[:force] || (resp = cache.read(cache_key)).nil?
|
31
|
-
log "#{resource_summary}"
|
32
|
-
resp = cache.write(cache_key, block.call(full_resource_path))
|
33
|
-
else
|
34
|
-
log "[CACHE] #{resource_summary}"
|
35
|
-
end
|
36
|
-
format.build(resp)
|
37
|
-
end
|
11
|
+
ATTRS = [:host, :user, :password, :expiration, :log_prefix]
|
12
|
+
ATTRS.each { |a| attr_reader a }
|
38
13
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
14
|
+
def initialize(args={})
|
15
|
+
ATTRS.each { |a| instance_variable_set("@#{a.to_s}", args.delete(a)) }
|
16
|
+
@cache = Resourceful::Resource::Cache.new @expiration
|
17
|
+
@logger = Log4r::Logger.new('[Resourceful]')
|
18
|
+
@logger.add(Log4r::StdoutOutputter.new('console'))
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
def call_resource(verb, path, opts={}, &block)
|
24
|
+
path, opts = check_config(path, opts)
|
25
|
+
format = Resourceful::Resource::Format.get(opts[:format])
|
50
26
|
|
51
|
-
|
52
|
-
|
53
|
-
|
27
|
+
full_resource_path = self.class.resource_path(path, format, opts[:params])
|
28
|
+
resource_summary = summary(verb.to_s, full_resource_path)
|
29
|
+
cache_key = Resourceful::Resource::Cache.key(@host, verb.to_s, full_resource_path)
|
54
30
|
|
55
|
-
|
56
|
-
"#{
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
@host
|
31
|
+
if opts[:force] || (resp = cache.read(cache_key)).nil?
|
32
|
+
log "#{resource_summary}"
|
33
|
+
resp = cache.write(cache_key, block.call(full_resource_path))
|
34
|
+
else
|
35
|
+
log "[CACHE] #{resource_summary}"
|
61
36
|
end
|
62
|
-
|
63
|
-
|
64
|
-
|
37
|
+
format.build(resp)
|
38
|
+
end
|
39
|
+
|
40
|
+
def check_config(path, opts) # :nodoc:
|
41
|
+
raise Resourceful::Exceptions::ConfigurationError, "invalid agent" unless agent && agent_url && !agent_url.empty?
|
42
|
+
opts ||= {}
|
43
|
+
opts[:force] ||= false
|
44
|
+
if path =~ /^(.+)\.(.+)$/
|
45
|
+
opts[:format] ||= $2
|
65
46
|
end
|
47
|
+
opts[:format] ||= Resourceful::Resource::Json.to_s
|
48
|
+
opts[:params] ||= {}
|
49
|
+
[path, opts]
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.resource_path(path, format, params) # :nodoc:
|
53
|
+
"#{path}#{params.to_http_query_str unless params.empty?}"
|
54
|
+
end
|
55
|
+
|
56
|
+
def summary(verb, full_resource_path) # :nodoc:
|
57
|
+
"#{verb.upcase} #{agent_url}#{full_resource_path}"
|
58
|
+
end
|
66
59
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
60
|
+
def agent_url
|
61
|
+
@host
|
62
|
+
end
|
63
|
+
|
64
|
+
def log(msg, level = :info) # :nodoc:
|
65
|
+
@logger.send(level.to_s, "#{"[#{@log_prefix.to_s}]" if @log_prefix} #{msg}") if msg
|
71
66
|
end
|
67
|
+
|
68
|
+
def log=(file)
|
69
|
+
@logger.add(Log4r::FileOutputter.new('fileOutputter', :filename => file, :trunc => false, :formatter => Log4r::PatternFormatter.new(:pattern => "[%l] %d :: %m"))) rescue nil
|
70
|
+
end
|
71
|
+
|
72
72
|
end
|
73
73
|
end
|
@@ -1,44 +1,44 @@
|
|
1
1
|
require 'mechanize'
|
2
2
|
require "resourceful/agent/base"
|
3
3
|
|
4
|
-
module Resourceful
|
5
|
-
module Agent
|
6
|
-
class Mechanize < Resourceful::Agent::Base
|
7
|
-
|
8
|
-
ATTRS = [:agent_alias, :verbose]
|
9
|
-
ATTRS.each { |a| attr_reader a }
|
10
|
-
|
11
|
-
def initialize(args={})
|
12
|
-
@verbose ||= false
|
13
|
-
ATTRS.each { |a| instance_variable_set("@#{a.to_s}", args.delete(a)) if args[a] }
|
14
|
-
super(args)
|
15
|
-
self.log = yield if block_given?
|
16
|
-
@mechanize = ::WWW::Mechanize.new do |obj|
|
17
|
-
obj.log = @logger && @verbose ? @logger : nil
|
18
|
-
obj.user_agent_alias = @agent_alias unless @agent_alias.nil?
|
19
|
-
end
|
20
|
-
end
|
4
|
+
module Resourceful; end
|
21
5
|
|
22
|
-
|
23
|
-
|
6
|
+
module Resourceful::Agent
|
7
|
+
class Mechanize < Resourceful::Agent::Base
|
8
|
+
|
9
|
+
ATTRS = [:agent_alias, :verbose]
|
10
|
+
ATTRS.each { |a| attr_reader a }
|
11
|
+
|
12
|
+
def initialize(args={})
|
13
|
+
@verbose ||= false
|
14
|
+
ATTRS.each { |a| instance_variable_set("@#{a.to_s}", args.delete(a)) if args[a] }
|
15
|
+
super(args)
|
16
|
+
self.log = yield if block_given?
|
17
|
+
@mechanize = ::WWW::Mechanize.new do |obj|
|
18
|
+
obj.log = @logger && @verbose ? @logger : nil
|
19
|
+
obj.user_agent_alias = @agent_alias unless @agent_alias.nil?
|
24
20
|
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def get(path, opts={}, &block)
|
24
|
+
call_resource(:get, path, opts, block)
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
25
28
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
resp =
|
31
|
-
@mechanize.send(verb.to_s, "#{@host}#{path}") do |page|
|
32
|
-
resp = block ? block.call(page) : page
|
33
|
-
end
|
34
|
-
resp.body
|
29
|
+
def call_resource(verb, path, opts, block)
|
30
|
+
super(verb, path, opts) do |path|
|
31
|
+
resp = ""
|
32
|
+
@mechanize.send(verb.to_s, "#{@host}#{path}") do |page|
|
33
|
+
resp = block ? block.call(page) : page
|
35
34
|
end
|
35
|
+
resp.body
|
36
36
|
end
|
37
|
-
|
38
|
-
def agent
|
39
|
-
@mechanize
|
40
|
-
end
|
41
|
-
|
42
37
|
end
|
38
|
+
|
39
|
+
def agent
|
40
|
+
@mechanize
|
41
|
+
end
|
42
|
+
|
43
43
|
end
|
44
44
|
end
|
@@ -1,56 +1,56 @@
|
|
1
1
|
require 'rest_client'
|
2
2
|
require "resourceful/agent/base"
|
3
3
|
|
4
|
-
module Resourceful
|
5
|
-
module Agent
|
6
|
-
class RestClient < Resourceful::Agent::Base
|
7
|
-
|
8
|
-
def initialize(args={})
|
9
|
-
super(args)
|
10
|
-
self.log = ::RestClient.log = yield if block_given?
|
11
|
-
@rest_client = ::RestClient::Resource.new(@host, :user => @user, :password => @password)
|
12
|
-
end
|
4
|
+
module Resourceful; end
|
13
5
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
6
|
+
module Resourceful::Agent
|
7
|
+
class RestClient < Resourceful::Agent::Base
|
8
|
+
|
9
|
+
def initialize(args={})
|
10
|
+
super(args)
|
11
|
+
self.log = ::RestClient.log = yield if block_given?
|
12
|
+
@rest_client = ::RestClient::Resource.new(@host, :user => @user, :password => @password)
|
13
|
+
end
|
14
|
+
|
15
|
+
def get(path, opts={}, &block)
|
16
|
+
call_resource(:get, path, opts, block)
|
17
|
+
end
|
18
|
+
|
19
|
+
def post(path, opts={}, body=nil, &block)
|
20
|
+
push_resource(:post, path, opts, body, block)
|
21
|
+
end
|
22
|
+
|
23
|
+
def put(path, opts={}, body=nil, &block)
|
24
|
+
push_resource(:put, path, opts, body, block)
|
25
|
+
end
|
26
|
+
|
27
|
+
def delete(path, opts={}, body=nil, &block)
|
28
|
+
push_resource(:delete, path, opts, body, block)
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
|
33
|
+
def push_resource(verb, path, opts, body, block)
|
34
|
+
opts[:body] = body
|
35
|
+
opts[:force] = true
|
36
|
+
call_resource(verb, path, opts, block)
|
37
|
+
end
|
38
|
+
|
39
|
+
def call_resource(verb, path, opts, block)
|
40
|
+
super(verb, path, opts) do |path|
|
41
|
+
result = case verb.to_sym
|
42
|
+
when :get
|
43
|
+
@rest_client[path].get
|
44
|
+
when :post, :put, :delete
|
45
|
+
@rest_client[path].send(verb, opts[:body])
|
47
46
|
end
|
47
|
+
block ? block.call(result) : result
|
48
48
|
end
|
49
|
-
|
50
|
-
def agent
|
51
|
-
@rest_client
|
52
|
-
end
|
53
|
-
|
54
49
|
end
|
50
|
+
|
51
|
+
def agent
|
52
|
+
@rest_client
|
53
|
+
end
|
54
|
+
|
55
55
|
end
|
56
56
|
end
|
@@ -1,23 +1,23 @@
|
|
1
|
-
module Resourceful
|
2
|
-
|
1
|
+
module Resourceful; end
|
2
|
+
|
3
|
+
module Resourceful::Exceptions
|
4
|
+
|
5
|
+
class ResourcefulError < ::StandardError
|
6
|
+
end
|
3
7
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end
|
18
|
-
|
19
|
-
class AttributeError < ModelError
|
20
|
-
end
|
21
|
-
|
8
|
+
class ResourceError < ResourcefulError
|
9
|
+
end
|
10
|
+
|
11
|
+
class ConfigurationError < ResourceError
|
12
|
+
end
|
13
|
+
|
14
|
+
class FormatError < ResourceError
|
15
|
+
end
|
16
|
+
|
17
|
+
class ModelError < ResourcefulError
|
18
|
+
end
|
19
|
+
|
20
|
+
class AttributeError < ModelError
|
22
21
|
end
|
22
|
+
|
23
23
|
end
|
@@ -1,198 +1,50 @@
|
|
1
|
-
module Resourceful
|
2
|
-
|
3
|
-
module NilClass
|
4
|
-
|
5
|
-
module ClassMethods; end
|
6
|
-
def self.included(klass)
|
7
|
-
klass.extend(ClassMethods) if klass.kind_of?(Class)
|
8
|
-
end
|
9
|
-
|
10
|
-
module ClassMethods
|
11
|
-
end
|
1
|
+
module Resourceful; end
|
2
|
+
module Resourceful::Extensions; end
|
12
3
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
4
|
+
module Resourceful::Extensions::String
|
5
|
+
|
6
|
+
module ClassMethods
|
20
7
|
end
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
unless "".respond_to?(:to_datetime)
|
36
|
-
def to_datetime
|
37
|
-
::DateTime.civil(*::Date._parse(self, false).values_at(:year, :mon, :mday, :hour, :min, :sec).map { |arg| arg || 0 }) rescue nil
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
unless "".respond_to?(:to_date)
|
42
|
-
def to_date
|
43
|
-
::Date.civil(*::Date._parse(self, false).values_at(:year, :mon, :mday).map { |arg| arg || 0 }) rescue nil
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
unless "".respond_to?(:to_resourceful_boolean)
|
48
|
-
def to_resourceful_boolean
|
49
|
-
self.nil? || self.empty? || self =~ /^(false|0)$/i ? false : true
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
unless "".respond_to?(:from_currency_to_f)
|
54
|
-
def from_currency_to_f
|
55
|
-
self.gsub(/[^0-9.-]/,'').to_f
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
unless "".respond_to?(:resourceful_constantize)
|
60
|
-
if Module.method(:const_get).arity == 1
|
61
|
-
def resourceful_constantize #:nodoc:
|
62
|
-
names = self.split('::')
|
63
|
-
names.shift if names.empty? || names.first.empty?
|
64
|
-
|
65
|
-
constant = ::Object
|
66
|
-
names.each do |name|
|
67
|
-
constant = constant.const_defined?(name) ? constant.const_get(name) : raise(NameError.new("uninitialized constant #{self}"))
|
68
|
-
end
|
69
|
-
constant
|
70
|
-
end
|
71
|
-
else # Ruby 1.9 version
|
72
|
-
def resourceful_constantize #:nodoc:
|
73
|
-
names = self.split('::')
|
74
|
-
names.shift if names.empty? || names.first.empty?
|
75
|
-
|
76
|
-
constant = ::Object
|
77
|
-
names.each do |name|
|
78
|
-
constant = constant.const_get(name, false) || raise(NameError.new("uninitialized constant #{self}"))
|
79
|
-
end
|
80
|
-
constant
|
8
|
+
|
9
|
+
module InstanceMethods
|
10
|
+
|
11
|
+
# Had to use a custom version of constantize to get around rails enhancements of 'const_missing'
|
12
|
+
# => instead, I just raise an uninitialized constant NameError manually
|
13
|
+
unless "".respond_to?(:resourceful_constantize)
|
14
|
+
if Module.method(:const_get).arity == 1
|
15
|
+
def resourceful_constantize #:nodoc:
|
16
|
+
names = self.split('::')
|
17
|
+
names.shift if names.empty? || names.first.empty?
|
18
|
+
|
19
|
+
constant = ::Object
|
20
|
+
names.each do |name|
|
21
|
+
constant = constant.const_defined?(name) ? constant.const_get(name) : raise(NameError.new("uninitialized constant #{self}"))
|
81
22
|
end
|
23
|
+
constant
|
82
24
|
end
|
83
|
-
|
25
|
+
else # Ruby 1.9 version
|
26
|
+
def resourceful_constantize #:nodoc:
|
27
|
+
names = self.split('::')
|
28
|
+
names.shift if names.empty? || names.first.empty?
|
84
29
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
if first_letter_in_uppercase
|
89
|
-
self.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
|
90
|
-
else
|
91
|
-
self[0..0].downcase + camelize(self)[1..-1]
|
30
|
+
constant = ::Object
|
31
|
+
names.each do |name|
|
32
|
+
constant = constant.const_get(name, false) || raise(NameError.new("uninitialized constant #{self}"))
|
92
33
|
end
|
34
|
+
constant
|
93
35
|
end
|
94
|
-
|
95
36
|
end
|
96
|
-
|
97
|
-
unless "".respond_to?(:underscore)
|
98
|
-
# "ActiveRecord::Errors".underscore # => active_record/errors
|
99
|
-
def underscore
|
100
|
-
self.to_s.gsub(/::/, '/').
|
101
|
-
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
102
|
-
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
103
|
-
tr("-", "_").
|
104
|
-
downcase
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
unless "".respond_to?(:demodulize)
|
109
|
-
# "ActiveRecord::CoreExtensions::String::Inflections".demodulize # => "Inflections"
|
110
|
-
def demodulize
|
111
|
-
self.to_s.gsub(/^.*::/, '')
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
37
|
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
module Resourceful
|
120
|
-
module Extensions
|
121
|
-
module Hash
|
122
38
|
|
123
|
-
module ClassMethods; end
|
124
|
-
def self.included(klass)
|
125
|
-
klass.extend(ClassMethods) if klass.kind_of?(Class)
|
126
|
-
end
|
127
|
-
|
128
|
-
module ClassMethods
|
129
|
-
end
|
130
|
-
|
131
|
-
# Returns string formatted for HTTP URL encoded name-value pairs.
|
132
|
-
# For example,
|
133
|
-
# {:id => 'thomas_hardy'}.to_http_query_str
|
134
|
-
# # => "?id=thomas_hardy"
|
135
|
-
# {:id => 23423, :since => Time.now}.to_http_query_str
|
136
|
-
# # => "?since=Thu,%2021%20Jun%202007%2012:10:05%20-0500&id=23423"
|
137
|
-
# {:id => [1,2]}.to_http_query_str
|
138
|
-
# # => "?id[]=1&id[]=2"
|
139
|
-
# {:poo => {:foo => 1, :bar => 2}}.to_http_query_str
|
140
|
-
# # => "?poo[bar]=2&poo[foo]=1"
|
141
|
-
# {:poo => {:foo => 1, :bar => {:bar1 => 1, :bar2 => "nasty"}}}.to_http_query_str
|
142
|
-
# "?poo[bar][bar1]=1&poo[bar][bar2]=nasty&poo[foo]=1"
|
143
|
-
unless {}.respond_to?(:to_http_query_str)
|
144
|
-
def to_http_query_str(opts = {})
|
145
|
-
require 'cgi' unless defined?(::CGI) && defined?(::CGI::escape)
|
146
|
-
opts[:prepend] ||= '?'
|
147
|
-
opts[:append] ||= ''
|
148
|
-
opts[:key_ns] ||= nil
|
149
|
-
opt_strings = self.collect do |key, val|
|
150
|
-
key_s = opts[:key_ns] ? "#{opts[:key_ns]}[#{key.to_s}]" : key.to_s
|
151
|
-
if val.kind_of?(::Array)
|
152
|
-
val.collect{|i| "#{key_s}[]=#{::CGI.escape(i.to_s)}"}.join('&')
|
153
|
-
elsif val.kind_of?(::Hash)
|
154
|
-
val.to_http_query_str({
|
155
|
-
:prepend => '',
|
156
|
-
:key_ns => key_s,
|
157
|
-
:append => ''
|
158
|
-
})
|
159
|
-
else
|
160
|
-
"#{key_s}=#{::CGI.escape(val.to_s)}"
|
161
|
-
end
|
162
|
-
end
|
163
|
-
self.empty? ? '' : "#{opts[:prepend]}#{opt_strings.join('&')}#{opts[:append]}"
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
# Returns the value for the provided key(s). Allows searching in nested hashes
|
168
|
-
unless {}.respond_to?(:get_value)
|
169
|
-
def get_value(*keys)
|
170
|
-
val = self[keys.first] || self[keys.first.to_s]
|
171
|
-
val = self[keys.first.to_s.intern] unless val || keys.first.to_s.empty? || keys.first.kind_of?(Symbol)
|
172
|
-
val.kind_of?(Hash) && keys.length > 1 ? val.get_value?(keys[1..-1]) : val
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
# Determines if a value exists for the provided key(s). Allows searching in nested hashes
|
177
|
-
unless {}.respond_to?('check_value?')
|
178
|
-
def check_value?(*keys)
|
179
|
-
val = self.get_value(keys)
|
180
|
-
val && !val.empty? ? true : false
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
end
|
185
39
|
end
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
end
|
40
|
+
|
41
|
+
def self.included(receiver)
|
42
|
+
receiver.extend ClassMethods
|
43
|
+
receiver.send :include, InstanceMethods
|
44
|
+
end
|
45
|
+
end
|
191
46
|
|
192
47
|
class String
|
193
48
|
include Resourceful::Extensions::String
|
194
49
|
end
|
195
50
|
|
196
|
-
class Hash
|
197
|
-
include Resourceful::Extensions::Hash
|
198
|
-
end
|