Class: MotionResource::Base
- Inherits:
-
Object
- Object
- MotionResource::Base
- Includes:
- MotionSupport::Callbacks, MotionSupport::DescendantsTracker
- Defined in:
- lib/motion-resource/base.rb,
lib/motion-resource/crud.rb,
lib/motion-resource/find.rb,
lib/motion-resource/urls.rb,
lib/motion-resource/logger.rb,
lib/motion-resource/requests.rb,
lib/motion-resource/callbacks.rb,
lib/motion-resource/attributes.rb,
lib/motion-resource/associations.rb
Constant Summary collapse
- HTTP_METHODS =
[:get, :post, :put, :delete]
Instance Attribute Summary collapse
-
#id ⇒ Object
Returns the value of attribute id.
Class Method Summary collapse
- .attribute(*fields) ⇒ Object
- .belongs_to(name, params = lambda { |o| Hash.new }) ⇒ Object
- .collection_url_or_default ⇒ Object
- .create(attributes = {}, &block) ⇒ Object
- .custom_urls(params = {}) ⇒ Object
- .delete(url, params = {}, &block) ⇒ Object
- .fetch_collection(url, &block) ⇒ Object
- .fetch_member(url, &block) ⇒ Object
- .find(id, params = {}, &block) ⇒ Object
- .find_all(params = {}, &block) ⇒ Object
- .get(url, params = {}, &block) ⇒ Object
- .has_many(name, options = {}) ⇒ Object
- .has_one(name) ⇒ Object
- .identity_map ⇒ Object
- .instantiate(json) ⇒ Object
- .member_url_or_default ⇒ Object
- .on_auth_failure(&block) ⇒ Object
- .post(url, params = {}, &block) ⇒ Object
- .put(url, params = {}, &block) ⇒ Object
- .recall(id) ⇒ Object
- .remember(id, value) ⇒ Object
- .request_block_call(block, default_arg, extra_arg) ⇒ Object
- .scope(name, options = {}) ⇒ Object
Instance Method Summary collapse
- #attributes ⇒ Object
- #collection_url(params = {}) ⇒ Object
- #create(&block) ⇒ Object
- #destroy(&block) ⇒ Object
-
#initialize(params = {}) ⇒ Base
constructor
A new instance of Base.
- #member_url(params = {}) ⇒ Object
- #new_record? ⇒ Boolean
- #reload(&block) ⇒ Object
- #save(&block) ⇒ Object
- #update(&block) ⇒ Object
- #update_attributes(params = {}) ⇒ Object
Constructor Details
#initialize(params = {}) ⇒ Base
Returns a new instance of Base.
10 11 12 13 |
# File 'lib/motion-resource/base.rb', line 10 def initialize(params = {}) @new_record = true update_attributes(params) end |
Instance Attribute Details
#id ⇒ Object
Returns the value of attribute id.
8 9 10 |
# File 'lib/motion-resource/base.rb', line 8 def id @id end |
Class Method Details
.attribute(*fields) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 19 |
# File 'lib/motion-resource/attributes.rb', line 7 def attribute(*fields) attr_reader *fields fields.each do |field| define_method "#{field}=" do |value| if value.is_a?(Hash) || value.is_a?(Array) instance_variable_set("@#{field}", value.dup) else instance_variable_set("@#{field}", value) end end end self.attributes += fields end |
.belongs_to(name, params = lambda { |o| Hash.new }) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/motion-resource/associations.rb', line 70 def belongs_to(name, params = lambda { |o| Hash.new }) define_method name do |&block| if block.nil? instance_variable_get("@#{name}") else if cached = instance_variable_get("@#{name}") cached_response = instance_variable_get("@#{name}_response") MotionResource::Base.request_block_call(block, cached, cached_response) return end Object.const_get(name.to_s.classify).find(self.send("#{name}_id"), params.call(self)) do |result, response| instance_variable_set("@#{name}", result) instance_variable_set("@#{name}_response", response) MotionResource::Base.request_block_call(block, result, response) end end end define_method "#{name}=" do |value| klass = Object.const_get(name.to_s.classify) value = klass.instantiate(value) if value.is_a?(Hash) instance_variable_set("@#{name}", value) end define_method "reset_#{name}" do instance_variable_set("@#{name}", nil) end end |
.collection_url_or_default ⇒ Object
20 21 22 |
# File 'lib/motion-resource/urls.rb', line 20 def collection_url_or_default collection_url || name.underscore.pluralize end |
.create(attributes = {}, &block) ⇒ Object
27 28 29 30 31 |
# File 'lib/motion-resource/crud.rb', line 27 def self.create(attributes = {}, &block) new(attributes).tap do |model| model.create(&block) end end |
.custom_urls(params = {}) ⇒ Object
9 10 11 12 13 14 15 16 17 18 |
# File 'lib/motion-resource/urls.rb', line 9 def custom_urls(params = {}) params.each do |name, url_format| define_method name do |params = {}| url_format.fill_url_params(params, self) end define_singleton_method name do url_format end end end |
.delete(url, params = {}, &block) ⇒ Object
24 25 26 |
# File 'lib/motion-resource/requests.rb', line 24 def delete(url, params = {}, &block) http_call(:delete, url, params, &block) end |
.fetch_collection(url, &block) ⇒ Object
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/motion-resource/find.rb', line 23 def fetch_collection(url, &block) get(url) do |response, json| if response.ok? objs = [] arr_rep = nil if json.class == Array arr_rep = json elsif json.class == Hash plural = self.name.underscore.pluralize if json.has_key?(plural) || json.has_key?(plural.to_sym) arr_rep = json[plural] || json[plural.to_sym] end else # the returned data was something else # ie a string, number request_block_call(block, nil, response) return end arr_rep.each { |one_obj_hash| objs << instantiate(one_obj_hash) } request_block_call(block, objs, response) else request_block_call(block, nil, response) end end end |
.fetch_member(url, &block) ⇒ Object
12 13 14 15 16 17 18 19 20 21 |
# File 'lib/motion-resource/find.rb', line 12 def fetch_member(url, &block) get(url) do |response, json| if response.ok? obj = instantiate(json) request_block_call(block, obj, response) else request_block_call(block, nil, response) end end end |
.find(id, params = {}, &block) ⇒ Object
4 5 6 |
# File 'lib/motion-resource/find.rb', line 4 def find(id, params = {}, &block) fetch_member(member_url_or_default.fill_url_params(params.merge(id: id)), &block) end |
.find_all(params = {}, &block) ⇒ Object
8 9 10 |
# File 'lib/motion-resource/find.rb', line 8 def find_all(params = {}, &block) fetch_collection(collection_url_or_default.fill_url_params(params), &block) end |
.get(url, params = {}, &block) ⇒ Object
12 13 14 |
# File 'lib/motion-resource/requests.rb', line 12 def get(url, params = {}, &block) http_call(:get, url, params, &block) end |
.has_many(name, options = {}) ⇒ Object
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 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/motion-resource/associations.rb', line 20 def has_many(name, = {}) = { :params => lambda { |o| Hash.new }, :class_name => name.to_s.classify } = .merge() backwards_association = self.name.underscore define_method name do |&block| if block.nil? instance_variable_get("@#{name}") || [] else if cached = instance_variable_get("@#{name}") cached_response = instance_variable_get("@#{name}_response") MotionResource::Base.request_block_call(block, cached, cached_response) return end klass = [:class_name].constantize klass.find_all([:params].call(self)) do |results, response| if results && results.first && results.first.respond_to?("#{backwards_association}=") results.each do |result| result.send("#{backwards_association}=", self) end end instance_variable_set("@#{name}", results) instance_variable_set("@#{name}_response", response) MotionResource::Base.request_block_call(block, results, response) end end end define_method "#{name}=" do |array| klass = [:class_name].constantize instance_variable_set("@#{name}", []) array.each do |value| value = klass.instantiate(value) if value.is_a?(Hash) instance_variable_get("@#{name}") << value end end define_method "reset_#{name}" do instance_variable_set("@#{name}", nil) end end |
.has_one(name) ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# File 'lib/motion-resource/associations.rb', line 4 def has_one(name) define_method name do instance_variable_get("@#{name}") end define_method "#{name}=" do |value| klass = Object.const_get(name.to_s.classify) value = klass.instantiate(value) if value.is_a?(Hash) instance_variable_set("@#{name}", value) end define_method "reset_#{name}" do instance_variable_set("@#{name}", nil) end end |
.identity_map ⇒ Object
44 45 46 |
# File 'lib/motion-resource/base.rb', line 44 def identity_map @identity_map ||= {} end |
.instantiate(json) ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/motion-resource/base.rb', line 20 def instantiate(json) json = json.symbolize_keys raise ArgumentError, "No :#{primary_key} parameter given for #{self.name}.instantiate" unless json[primary_key] klass = if json[:type] begin Object.const_get(json[:type].to_s) rescue NameError self end else self end if result = klass.recall(json[primary_key]) result.update_attributes(json) else result = klass.new(json) klass.remember(result.send(result.primary_key), result) end result.send(:instance_variable_set, "@new_record", false) result end |
.member_url_or_default ⇒ Object
24 25 26 |
# File 'lib/motion-resource/urls.rb', line 24 def member_url_or_default member_url || "#{name.underscore.pluralize}/:#{primary_key}" end |
.on_auth_failure(&block) ⇒ Object
28 29 30 |
# File 'lib/motion-resource/requests.rb', line 28 def on_auth_failure(&block) @on_auth_failure = block end |
.post(url, params = {}, &block) ⇒ Object
16 17 18 |
# File 'lib/motion-resource/requests.rb', line 16 def post(url, params = {}, &block) http_call(:post, url, params, &block) end |
.put(url, params = {}, &block) ⇒ Object
20 21 22 |
# File 'lib/motion-resource/requests.rb', line 20 def put(url, params = {}, &block) http_call(:put, url, params, &block) end |
.recall(id) ⇒ Object
52 53 54 |
# File 'lib/motion-resource/base.rb', line 52 def recall(id) identity_map[id] end |
.remember(id, value) ⇒ Object
48 49 50 |
# File 'lib/motion-resource/base.rb', line 48 def remember(id, value) identity_map[id] = value end |
.request_block_call(block, default_arg, extra_arg) ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/motion-resource/find.rb', line 51 def request_block_call(block, default_arg, extra_arg) if block if block.arity == 1 block.call default_arg elsif block.arity == 2 block.call default_arg, extra_arg else raise "Not enough arguments to block" end else raise "No block given" end end |
.scope(name, options = {}) ⇒ Object
102 103 104 105 106 107 108 |
# File 'lib/motion-resource/associations.rb', line 102 def scope(name, = {}) custom_urls "#{name}_url" => [:url] if [:url] .send(:define_method, name) do |&block| fetch_collection(send("#{name}_url"), &block) end end |
Instance Method Details
#attributes ⇒ Object
31 32 33 34 35 36 |
# File 'lib/motion-resource/attributes.rb', line 31 def attributes self.class.attributes.inject({}) do |hash, attr| hash[attr] = send(attr) hash end end |
#collection_url(params = {}) ⇒ Object
29 30 31 |
# File 'lib/motion-resource/urls.rb', line 29 def collection_url(params = {}) self.class.collection_url_or_default.fill_url_params(params, self) end |
#create(&block) ⇒ Object
17 18 19 20 21 22 23 24 25 |
# File 'lib/motion-resource/crud.rb', line 17 def create(&block) # weird heisenbug: Specs crash without that line :( dummy = self run_callbacks :create do self.class.post(collection_url, :payload => { self.class.name.underscore => attributes }) do |response, json| self.class.request_block_call(block, json.blank? ? self : self.class.instantiate(json), response) if block end end end |
#destroy(&block) ⇒ Object
33 34 35 36 37 38 39 |
# File 'lib/motion-resource/crud.rb', line 33 def destroy(&block) run_callbacks :destroy do self.class.delete(member_url) do |response, json| self.class.request_block_call(block, json.blank? ? nil : self.class.instantiate(json), response) if block end end end |
#member_url(params = {}) ⇒ Object
33 34 35 |
# File 'lib/motion-resource/urls.rb', line 33 def member_url(params = {}) self.class.member_url_or_default.fill_url_params(params, self) end |
#new_record? ⇒ Boolean
15 16 17 |
# File 'lib/motion-resource/base.rb', line 15 def new_record? @new_record end |
#reload(&block) ⇒ Object
41 42 43 44 45 |
# File 'lib/motion-resource/crud.rb', line 41 def reload(&block) self.class.get(member_url) do |response, json| self.class.request_block_call(block, json.blank? ? nil : self.class.instantiate(json), response) if block end end |
#save(&block) ⇒ Object
3 4 5 6 7 |
# File 'lib/motion-resource/crud.rb', line 3 def save(&block) run_callbacks :save do @new_record ? create(&block) : update(&block) end end |
#update(&block) ⇒ Object
9 10 11 12 13 14 15 |
# File 'lib/motion-resource/crud.rb', line 9 def update(&block) run_callbacks :update do self.class.put(member_url, :payload => { self.class.name.underscore => attributes }) do |response, json| self.class.request_block_call(block, json.blank? ? self : self.class.instantiate(json), response) if block end end end |
#update_attributes(params = {}) ⇒ Object
22 23 24 25 26 27 28 29 |
# File 'lib/motion-resource/attributes.rb', line 22 def update_attributes(params = {}) attributes = self.methods - Object.methods params.each do |key, value| if attributes.member?((key.to_s + "=:").to_sym) self.send((key.to_s + "=:").to_sym, value) end end end |