morpheus 0.4.0 → 0.5.0
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/.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
|