morpheus 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -1
- data/CHANGELOG.md +17 -0
- data/Gemfile +1 -1
- data/lib/morpheus.rb +3 -23
- data/lib/morpheus/base.rb +11 -11
- data/lib/morpheus/client.rb +10 -0
- data/lib/morpheus/client/associations.rb +6 -6
- data/lib/morpheus/client/cached_request_formatter.rb +20 -0
- data/lib/morpheus/client/log_subscriber.rb +2 -28
- data/lib/morpheus/client/railtie.rb +4 -4
- data/lib/morpheus/client/request_formatter.rb +50 -0
- data/lib/morpheus/client/uncached_request_formatter.rb +40 -0
- data/lib/morpheus/configuration.rb +30 -9
- data/lib/morpheus/mixins.rb +16 -0
- data/lib/morpheus/mixins/associations.rb +39 -37
- data/lib/morpheus/mixins/associations/association.rb +112 -0
- data/lib/morpheus/mixins/associations/belongs_to_association.rb +47 -0
- data/lib/morpheus/mixins/associations/has_many_association.rb +72 -0
- data/lib/morpheus/mixins/associations/has_one_association.rb +48 -0
- data/lib/morpheus/mixins/attributes.rb +97 -95
- data/lib/morpheus/mixins/conversion.rb +16 -14
- data/lib/morpheus/mixins/filtering.rb +13 -11
- data/lib/morpheus/mixins/finders.rb +47 -45
- data/lib/morpheus/mixins/introspection.rb +15 -13
- data/lib/morpheus/mixins/persistence.rb +32 -30
- data/lib/morpheus/mixins/reflections.rb +17 -15
- data/lib/morpheus/mixins/request_handling.rb +27 -25
- data/lib/morpheus/mixins/response_parsing.rb +10 -8
- data/lib/morpheus/mixins/url_support.rb +27 -25
- data/lib/morpheus/reflection.rb +5 -2
- data/lib/morpheus/type_caster.rb +1 -1
- data/lib/morpheus/version.rb +1 -1
- data/morpheus.gemspec +2 -2
- data/spec/dummy/app/resources/book.rb +1 -1
- data/spec/morpheus/base_spec.rb +35 -35
- data/spec/morpheus/client/cached_request_formatter_spec.rb +28 -0
- data/spec/morpheus/client/log_subscriber_spec.rb +53 -10
- data/spec/morpheus/client/request_formatter_spec.rb +5 -0
- data/spec/morpheus/client/uncached_request_formatter_spec.rb +29 -0
- data/spec/morpheus/configuration_spec.rb +49 -11
- data/spec/morpheus/{associations → mixins/associations}/association_spec.rb +1 -1
- data/spec/morpheus/{associations → mixins/associations}/belongs_to_association_spec.rb +1 -1
- data/spec/morpheus/{associations → mixins/associations}/has_many_association_spec.rb +1 -1
- data/spec/morpheus/{associations → mixins/associations}/has_one_association_spec.rb +1 -1
- data/spec/morpheus/mixins/associations_spec.rb +1 -1
- data/spec/morpheus/mixins/attributes_spec.rb +27 -6
- data/spec/morpheus/mixins/conversion_spec.rb +1 -1
- data/spec/morpheus/mixins/filtering_spec.rb +2 -2
- data/spec/morpheus/mixins/finders_spec.rb +1 -1
- data/spec/morpheus/mixins/introspection_spec.rb +1 -1
- data/spec/morpheus/mixins/persistence_spec.rb +1 -1
- data/spec/morpheus/mixins/reflections_spec.rb +1 -1
- data/spec/morpheus/mixins/request_handling_spec.rb +2 -2
- data/spec/morpheus/mixins/response_parsing_spec.rb +2 -2
- data/spec/morpheus/mixins/url_support_spec.rb +2 -2
- data/spec/morpheus/response_parser_spec.rb +5 -1
- data/spec/regressions/sorting_resources_spec.rb +119 -0
- data/spec/spec_helper.rb +3 -2
- metadata +159 -87
- data/lib/morpheus/associations/association.rb +0 -110
- data/lib/morpheus/associations/belongs_to_association.rb +0 -45
- data/lib/morpheus/associations/has_many_association.rb +0 -70
- data/lib/morpheus/associations/has_one_association.rb +0 -46
data/.rspec
CHANGED
@@ -1 +1 @@
|
|
1
|
-
--
|
1
|
+
--order rand
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# 0.5.0
|
2
|
+
* Upgrading typhoeus to ~> 0.4.2
|
3
|
+
* Morpheus::Client::LogSubscriber has been refactored out into separate formatter classes.
|
4
|
+
|
5
|
+
# 0.4.0
|
6
|
+
* Updated yajl-ruby to ~> 1.1.0 [3f30762](https://github.com/ryanmoran/morpheus/commit/3f30762528f4fc6b1f35775ce81e5ba1c03bc3c7).
|
7
|
+
* Updated typhoeus to ~> 0.3.3 [cf474b6](https://github.com/ryanmoran/morpheus/commit/cf474b651a77a8359ebb25600ab2be8a57a06df2).
|
8
|
+
* Added Yajl::ParseError exception handling support [3234984](https://github.com/ryanmoran/morpheus/commit/32349841d155188fe37906351f5091e756deca76).
|
9
|
+
* Continuing to add spec coverage.
|
10
|
+
|
11
|
+
# 0.3.9
|
12
|
+
* Fixed ResponseCache hashing issue where duplicate cache_key values were being created for different responses [5b507a7](https://github.com/ryanmoran/morpheus/commit/5b507a78e53120239ad38df0018b7324bd5969e9).
|
13
|
+
* Continuing to add spec coverage.
|
14
|
+
|
15
|
+
# 0.3.8
|
16
|
+
* Fixed dependency version issues with activemodel, activesupport, and i18n [36575ef](https://github.com/ryanmoran/morpheus/commit/36575efe6ca42edf1e7b461658c55048823730f7).
|
17
|
+
* Continuing to add spec coverage.
|
data/Gemfile
CHANGED
data/lib/morpheus.rb
CHANGED
@@ -13,11 +13,11 @@ require 'active_model'
|
|
13
13
|
# The bulk of the library consists of the Base class and its mix-in modules, the request/response wrappers,
|
14
14
|
# mocking, configuration, errors, and classes managing associations, reflections, relations, and typecasting.
|
15
15
|
module Morpheus
|
16
|
-
autoload :Version, 'morpheus/version'
|
17
|
-
|
18
16
|
autoload :Base, 'morpheus/base'
|
17
|
+
autoload :Client, 'morpheus/client'
|
19
18
|
autoload :Configuration, 'morpheus/configuration'
|
20
19
|
autoload :Filter, 'morpheus/filter'
|
20
|
+
autoload :Mixins, 'morpheus/mixins'
|
21
21
|
autoload :Mock, 'morpheus/mock'
|
22
22
|
autoload :Reflection, 'morpheus/reflection'
|
23
23
|
autoload :Relation, 'morpheus/relation'
|
@@ -28,19 +28,7 @@ module Morpheus
|
|
28
28
|
autoload :ResponseParser, 'morpheus/response_parser'
|
29
29
|
autoload :TypeCaster, 'morpheus/type_caster'
|
30
30
|
autoload :UrlBuilder, 'morpheus/url_builder'
|
31
|
-
|
32
|
-
# Mixins provide behaviors to the Base class.
|
33
|
-
autoload :Associations, 'morpheus/mixins/associations'
|
34
|
-
autoload :Attributes, 'morpheus/mixins/attributes'
|
35
|
-
autoload :Conversion, 'morpheus/mixins/conversion'
|
36
|
-
autoload :Filtering, 'morpheus/mixins/filtering'
|
37
|
-
autoload :Finders, 'morpheus/mixins/finders'
|
38
|
-
autoload :Introspection, 'morpheus/mixins/introspection'
|
39
|
-
autoload :Persistence, 'morpheus/mixins/persistence'
|
40
|
-
autoload :Reflections, 'morpheus/mixins/reflections'
|
41
|
-
autoload :RequestHandling, 'morpheus/mixins/request_handling'
|
42
|
-
autoload :ResponseParsing, 'morpheus/mixins/response_parsing'
|
43
|
-
autoload :UrlSupport, 'morpheus/mixins/url_support'
|
31
|
+
autoload :Version, 'morpheus/version'
|
44
32
|
|
45
33
|
# Error classes
|
46
34
|
autoload :ConfigurationError, 'morpheus/errors'
|
@@ -52,14 +40,6 @@ module Morpheus
|
|
52
40
|
autoload :InvalidResponseCode, 'morpheus/errors'
|
53
41
|
end
|
54
42
|
|
55
|
-
# Associations for application objects, typically ActiveRecord, to resource
|
56
|
-
module Morpheus
|
57
|
-
module Client
|
58
|
-
autoload :Associations, 'morpheus/client/associations'
|
59
|
-
autoload :LogSubscriber, 'morpheus/client/log_subscriber'
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
43
|
# The Railtie loads the LogSubscriber for printing output to the Rails log, and
|
64
44
|
# Associations which plug-in to ActiveRecord to link associated resources.
|
65
45
|
require 'morpheus/client/railtie' if defined?(Rails)
|
data/lib/morpheus/base.rb
CHANGED
@@ -17,17 +17,17 @@ module Morpheus
|
|
17
17
|
# In many cases they rely upon other classes in the library to complete
|
18
18
|
# their functionality. The helper classes can be used stand-alone, but
|
19
19
|
# are most effective when used as collaborators to the mix-in behaviors.
|
20
|
-
include Associations
|
21
|
-
include Attributes
|
22
|
-
include Conversion
|
23
|
-
include Filtering
|
24
|
-
include Finders
|
25
|
-
include Introspection
|
26
|
-
include Persistence
|
27
|
-
include Reflections
|
28
|
-
include RequestHandling
|
29
|
-
include ResponseParsing
|
30
|
-
include UrlSupport
|
20
|
+
include Mixins::Associations
|
21
|
+
include Mixins::Attributes
|
22
|
+
include Mixins::Conversion
|
23
|
+
include Mixins::Filtering
|
24
|
+
include Mixins::Finders
|
25
|
+
include Mixins::Introspection
|
26
|
+
include Mixins::Persistence
|
27
|
+
include Mixins::Reflections
|
28
|
+
include Mixins::RequestHandling
|
29
|
+
include Mixins::ResponseParsing
|
30
|
+
include Mixins::UrlSupport
|
31
31
|
|
32
32
|
# Defines a default 'id' property on all instances of Morpheus::Base and subclasses
|
33
33
|
property :id, :integer
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# Associations for application objects, typically ActiveRecord, to resource
|
2
|
+
module Morpheus
|
3
|
+
module Client
|
4
|
+
autoload :Associations, 'morpheus/client/associations'
|
5
|
+
autoload :CachedRequestFormatter, 'morpheus/client/cached_request_formatter'
|
6
|
+
autoload :LogSubscriber, 'morpheus/client/log_subscriber'
|
7
|
+
autoload :RequestFormatter, 'morpheus/client/request_formatter'
|
8
|
+
autoload :UncachedRequestFormatter, 'morpheus/client/uncached_request_formatter'
|
9
|
+
end
|
10
|
+
end
|
@@ -11,11 +11,11 @@ module Morpheus
|
|
11
11
|
def belongs_to_resource(association, options = {})
|
12
12
|
define_method association do
|
13
13
|
instance_variable_get("@#{association}") ||
|
14
|
-
instance_variable_set("@#{association}", Morpheus::Associations::BelongsToAssociation.new(self, association, :options => options))
|
14
|
+
instance_variable_set("@#{association}", Morpheus::Mixins::Associations::BelongsToAssociation.new(self, association, :options => options))
|
15
15
|
end
|
16
16
|
|
17
17
|
define_method "#{association}=" do |target|
|
18
|
-
instance_variable_set("@#{association}", Morpheus::Associations::BelongsToAssociation.new(self, association, :target => target, :options => options))
|
18
|
+
instance_variable_set("@#{association}", Morpheus::Mixins::Associations::BelongsToAssociation.new(self, association, :target => target, :options => options))
|
19
19
|
send("#{association}_id=", target.id)
|
20
20
|
end
|
21
21
|
|
@@ -24,22 +24,22 @@ module Morpheus
|
|
24
24
|
def has_many_resources(association, options = {})
|
25
25
|
define_method association do
|
26
26
|
instance_variable_get("@#{association}") ||
|
27
|
-
instance_variable_set("@#{association}", Morpheus::Associations::HasManyAssociation.new(self, association, :options => options))
|
27
|
+
instance_variable_set("@#{association}", Morpheus::Mixins::Associations::HasManyAssociation.new(self, association, :options => options))
|
28
28
|
end
|
29
29
|
|
30
30
|
define_method "#{association}=" do |target|
|
31
|
-
instance_variable_set("@#{association}", Morpheus::Associations::HasManyAssociation.new(self, association, :target => target, :options => options))
|
31
|
+
instance_variable_set("@#{association}", Morpheus::Mixins::Associations::HasManyAssociation.new(self, association, :target => target, :options => options))
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
35
|
def has_one_resource(association, options = {})
|
36
36
|
define_method association do
|
37
37
|
instance_variable_get("@#{association}") ||
|
38
|
-
instance_variable_set("@#{association}", Morpheus::Associations::HasOneAssociation.new(self, association, :options => options))
|
38
|
+
instance_variable_set("@#{association}", Morpheus::Mixins::Associations::HasOneAssociation.new(self, association, :options => options))
|
39
39
|
end
|
40
40
|
|
41
41
|
define_method "#{association}=" do |target|
|
42
|
-
instance_variable_set("@#{association}", Morpheus::Associations::HasOneAssociation.new(self, association, :target => target, :options => options))
|
42
|
+
instance_variable_set("@#{association}", Morpheus::Mixins::Associations::HasOneAssociation.new(self, association, :target => target, :options => options))
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Morpheus
|
2
|
+
module Client
|
3
|
+
class CachedRequestFormatter < RequestFormatter
|
4
|
+
|
5
|
+
def call
|
6
|
+
"#{request_statement} #{payload}"
|
7
|
+
end
|
8
|
+
|
9
|
+
def request_statement
|
10
|
+
statement = "CACHE (#{duration}ms)"
|
11
|
+
color(statement, request_color, true)
|
12
|
+
end
|
13
|
+
|
14
|
+
def duration
|
15
|
+
event.duration
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -12,37 +12,11 @@ module Morpheus
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def uncached_request(event)
|
15
|
-
|
16
|
-
request_statement = "#{event.payload[:class].to_s} #{event.payload[:method].to_s.upcase} (#{duration}ms)"
|
17
|
-
if odd?
|
18
|
-
request_statement = color(request_statement, MAGENTA, true)
|
19
|
-
payload = color(payload(event), nil, true)
|
20
|
-
else
|
21
|
-
request_statement = color(request_statement, CYAN, true)
|
22
|
-
payload = payload(event)
|
23
|
-
end
|
24
|
-
|
25
|
-
response_color = case event.payload[:response].code
|
26
|
-
when 200..299 then GREEN
|
27
|
-
when 400..599 then RED
|
28
|
-
else YELLOW
|
29
|
-
end
|
30
|
-
response_statement = color("[#{event.payload[:response].code}]", response_color, true)
|
31
|
-
|
32
|
-
"#{request_statement} #{response_statement} #{payload}"
|
15
|
+
UncachedRequestFormatter.call(self, event, odd?)
|
33
16
|
end
|
34
17
|
|
35
18
|
def cached_request(event)
|
36
|
-
|
37
|
-
request_statement = "CACHE (#{duration}ms)"
|
38
|
-
if odd?
|
39
|
-
request_statement = color(request_statement, MAGENTA, true)
|
40
|
-
payload = color(payload(event), nil, true)
|
41
|
-
else
|
42
|
-
request_statement = color(request_statement, CYAN, true)
|
43
|
-
payload = payload(event)
|
44
|
-
end
|
45
|
-
"#{request_statement} #{payload}"
|
19
|
+
CachedRequestFormatter.call(self, event, odd?)
|
46
20
|
end
|
47
21
|
|
48
22
|
def payload(event)
|
@@ -4,19 +4,19 @@ module Morpheus
|
|
4
4
|
|
5
5
|
if defined?(ActiveRecord)
|
6
6
|
ActiveRecord::Base.send(:include, Morpheus::Client::Associations)
|
7
|
-
ActiveRecord::Base.send(:include, Morpheus::UrlSupport)
|
7
|
+
ActiveRecord::Base.send(:include, Morpheus::Mixins::UrlSupport)
|
8
8
|
end
|
9
9
|
|
10
|
-
initializer
|
10
|
+
initializer 'morpheus.client.configure_request_cache' do |app|
|
11
11
|
app.middleware.use Morpheus::RequestQueue
|
12
12
|
app.middleware.use Morpheus::RequestCache
|
13
13
|
end
|
14
14
|
|
15
|
-
initializer
|
15
|
+
initializer 'morpheus.configure_logger', :after => :initialize_logger do |app|
|
16
16
|
Morpheus::Configuration.logger = Rails.logger
|
17
17
|
end
|
18
18
|
|
19
|
-
initializer
|
19
|
+
initializer 'morpheus.client.log_subscriber', :after => 'morpheus.configure_logger' do
|
20
20
|
Morpheus::Client::LogSubscriber.attach_to :morpheus
|
21
21
|
end
|
22
22
|
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Morpheus
|
2
|
+
module Client
|
3
|
+
class RequestFormatter
|
4
|
+
MAGENTA = ActiveSupport::LogSubscriber::MAGENTA
|
5
|
+
CYAN = ActiveSupport::LogSubscriber::CYAN
|
6
|
+
GREEN = ActiveSupport::LogSubscriber::GREEN
|
7
|
+
RED = ActiveSupport::LogSubscriber::RED
|
8
|
+
YELLOW = ActiveSupport::LogSubscriber::YELLOW
|
9
|
+
|
10
|
+
attr_reader :subscriber, :event
|
11
|
+
|
12
|
+
def self.call(subscriber, event, odd)
|
13
|
+
new(subscriber, event, odd).call
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(subscriber, event, odd)
|
17
|
+
@subscriber = subscriber
|
18
|
+
@event = event
|
19
|
+
@odd = odd
|
20
|
+
end
|
21
|
+
|
22
|
+
def odd?
|
23
|
+
@odd
|
24
|
+
end
|
25
|
+
|
26
|
+
def payload
|
27
|
+
if odd?
|
28
|
+
color(formatted_payload, nil, true)
|
29
|
+
else
|
30
|
+
formatted_payload
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def color(*args)
|
35
|
+
subscriber.send(:color, *args)
|
36
|
+
end
|
37
|
+
|
38
|
+
def formatted_payload
|
39
|
+
payload = "#{event.payload[:url]}"
|
40
|
+
payload << " #{event.payload[:params].inspect}" unless event.payload[:params].blank?
|
41
|
+
payload
|
42
|
+
end
|
43
|
+
|
44
|
+
def request_color
|
45
|
+
odd? ? MAGENTA : CYAN
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Morpheus
|
2
|
+
module Client
|
3
|
+
class UncachedRequestFormatter < RequestFormatter
|
4
|
+
|
5
|
+
def call
|
6
|
+
"#{request_statement} #{response_statement} #{payload}"
|
7
|
+
end
|
8
|
+
|
9
|
+
def request_statement
|
10
|
+
klass = event.payload[:class]
|
11
|
+
method = event.payload[:method].to_s.upcase
|
12
|
+
statement = "#{klass} #{method} (#{duration})"
|
13
|
+
color(statement, request_color, true)
|
14
|
+
end
|
15
|
+
|
16
|
+
def response_statement
|
17
|
+
statement = "[#{response.code}]"
|
18
|
+
color(statement, response_color, true)
|
19
|
+
end
|
20
|
+
|
21
|
+
def response
|
22
|
+
event.payload[:response]
|
23
|
+
end
|
24
|
+
|
25
|
+
def duration
|
26
|
+
value = response.time * 1000
|
27
|
+
"#{value}ms"
|
28
|
+
end
|
29
|
+
|
30
|
+
def response_color
|
31
|
+
case response.code
|
32
|
+
when 200..299 then GREEN
|
33
|
+
when 400..599 then RED
|
34
|
+
else YELLOW
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -2,33 +2,54 @@ module Morpheus
|
|
2
2
|
module Configuration
|
3
3
|
extend self
|
4
4
|
|
5
|
-
|
5
|
+
def attributes
|
6
|
+
@attributes ||= {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def username=(username)
|
10
|
+
attributes[:username] = username
|
11
|
+
end
|
12
|
+
|
13
|
+
def username
|
14
|
+
attributes[:username]
|
15
|
+
end
|
16
|
+
|
17
|
+
def password=(password)
|
18
|
+
attributes[:password] = password
|
19
|
+
end
|
20
|
+
|
21
|
+
def password
|
22
|
+
attributes[:password]
|
23
|
+
end
|
6
24
|
|
7
25
|
# Sets and gets the remote host service domain.
|
8
26
|
# The domain must be set before any requests can be made.
|
9
|
-
|
27
|
+
def host=(host)
|
28
|
+
attributes[:host] = host
|
29
|
+
end
|
30
|
+
|
10
31
|
def host
|
11
|
-
|
32
|
+
attributes[:host] || raise(Morpheus::ConfigurationError,
|
12
33
|
'The request HOST has not been set. Please set the host using Morpheus::Configuration.host = "http://www.example.com"')
|
13
34
|
end
|
14
35
|
|
15
36
|
# Links to the underlying libcurl request pool.
|
16
37
|
# Allows for concurrent requests.
|
17
38
|
def hydra
|
18
|
-
Typhoeus::Hydra.hydra
|
39
|
+
attributes[:hydra] ||= Typhoeus::Hydra.hydra
|
19
40
|
end
|
20
41
|
|
21
42
|
def hydra=(hydra)
|
22
|
-
Typhoeus::Hydra.hydra = hydra
|
43
|
+
attributes[:hydra] = Typhoeus::Hydra.hydra = hydra
|
23
44
|
end
|
24
45
|
|
25
46
|
# Handles the default logger that is used by the LogSubscriber
|
26
47
|
def logger
|
27
|
-
|
48
|
+
attributes[:logger] ||= ::Logger.new(STDOUT)
|
28
49
|
end
|
29
50
|
|
30
51
|
def logger=(logger)
|
31
|
-
|
52
|
+
attributes[:logger] = logger
|
32
53
|
end
|
33
54
|
|
34
55
|
# Can be set or unset to allow for test suite mocking.
|
@@ -44,11 +65,11 @@ module Morpheus
|
|
44
65
|
end
|
45
66
|
|
46
67
|
def parse_error_handler
|
47
|
-
|
68
|
+
attributes[:parse_error_handler]
|
48
69
|
end
|
49
70
|
|
50
71
|
def parse_error_handler=(handler)
|
51
|
-
|
72
|
+
attributes[:parse_error_handler] = handler
|
52
73
|
end
|
53
74
|
|
54
75
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Mixins provide behaviors to support the Base class.
|
2
|
+
module Morpheus
|
3
|
+
module Mixins
|
4
|
+
autoload :Associations, 'morpheus/mixins/associations'
|
5
|
+
autoload :Attributes, 'morpheus/mixins/attributes'
|
6
|
+
autoload :Conversion, 'morpheus/mixins/conversion'
|
7
|
+
autoload :Filtering, 'morpheus/mixins/filtering'
|
8
|
+
autoload :Finders, 'morpheus/mixins/finders'
|
9
|
+
autoload :Introspection, 'morpheus/mixins/introspection'
|
10
|
+
autoload :Persistence, 'morpheus/mixins/persistence'
|
11
|
+
autoload :Reflections, 'morpheus/mixins/reflections'
|
12
|
+
autoload :RequestHandling, 'morpheus/mixins/request_handling'
|
13
|
+
autoload :ResponseParsing, 'morpheus/mixins/response_parsing'
|
14
|
+
autoload :UrlSupport, 'morpheus/mixins/url_support'
|
15
|
+
end
|
16
|
+
end
|
@@ -1,57 +1,59 @@
|
|
1
1
|
module Morpheus
|
2
|
-
module
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
2
|
+
module Mixins
|
3
|
+
module Associations
|
4
|
+
autoload :Association, 'morpheus/mixins/associations/association'
|
5
|
+
autoload :BelongsToAssociation, 'morpheus/mixins/associations/belongs_to_association'
|
6
|
+
autoload :HasManyAssociation, 'morpheus/mixins/associations/has_many_association'
|
7
|
+
autoload :HasOneAssociation, 'morpheus/mixins/associations/has_one_association'
|
8
|
+
|
9
|
+
def self.included(base)
|
10
|
+
base.extend(ClassMethods)
|
11
|
+
end
|
11
12
|
|
12
|
-
|
13
|
+
module ClassMethods
|
13
14
|
|
14
|
-
|
15
|
-
|
15
|
+
def belongs_to(association, options = {})
|
16
|
+
attribute_id_sym = "#{association}_id".to_sym
|
16
17
|
|
17
|
-
|
18
|
+
property attribute_id_sym
|
18
19
|
|
19
|
-
|
20
|
+
create_reflection(:belongs_to, association, options)
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
define_method association do
|
23
|
+
instance_variable_get("@#{association}") ||
|
24
|
+
instance_variable_set("@#{association}", BelongsToAssociation.new(self, association, :options => options))
|
25
|
+
end
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
27
|
+
define_method "#{association}=" do |target|
|
28
|
+
instance_variable_set("@#{association}", BelongsToAssociation.new(self, association, :target => target, :options => options))
|
29
|
+
send("#{association}_id=", target.id)
|
30
|
+
end
|
29
31
|
end
|
30
|
-
end
|
31
32
|
|
32
|
-
|
33
|
-
|
33
|
+
def has_many(association, options = {})
|
34
|
+
create_reflection(:has_many, association, options)
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
|
36
|
+
define_method association do
|
37
|
+
instance_variable_get("@#{association}") ||
|
38
|
+
instance_variable_set("@#{association}", HasManyAssociation.new(self, association, :options => options))
|
39
|
+
end
|
38
40
|
end
|
39
|
-
end
|
40
41
|
|
41
|
-
|
42
|
-
|
42
|
+
def has_one(association, options = {})
|
43
|
+
create_reflection(:has_one, association, options)
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
45
|
+
define_method association do
|
46
|
+
instance_variable_get("@#{association}") ||
|
47
|
+
instance_variable_set("@#{association}", HasOneAssociation.new(self, association, :options => options))
|
48
|
+
end
|
48
49
|
|
49
|
-
|
50
|
-
|
50
|
+
define_method "#{association}=" do |target|
|
51
|
+
instance_variable_set("@#{association}", HasOneAssociation.new(self, association, :target => target, :options => options))
|
52
|
+
end
|
51
53
|
end
|
54
|
+
|
52
55
|
end
|
53
56
|
|
54
57
|
end
|
55
|
-
|
56
58
|
end
|
57
59
|
end
|