storage_room 0.3.9 → 0.3.10

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,7 @@
1
+ == Version 0.3.10
2
+ * Fixed cyclic dependency when preloading associated Collections
3
+ * Added create, update, save and destroy callbacks to Models
4
+
1
5
  == Version 0.3.9
2
6
  * Added a check that already defined classes inherit from StorageRoom::Entry
3
7
 
data/README.rdoc CHANGED
@@ -9,6 +9,7 @@ This gem provides read and write access to the StorageRoom API (http://storagero
9
9
  * Supports lazy-loading of associations (e.g. post.category will fetch a category transparently if it has not yet been loaded)
10
10
  * Supports caching through an identity map, so that Resources don't have to be loaded multiple times
11
11
  * Easy file uploads and removals
12
+ * Model Callbacks
12
13
 
13
14
  == Installation
14
15
 
data/Rakefile CHANGED
@@ -15,6 +15,7 @@ begin
15
15
 
16
16
  gem.add_dependency 'httparty', '>= 0.6.1'
17
17
  gem.add_dependency 'activesupport', '>= 3.0.0'
18
+ gem.add_dependency 'activemodel', '>= 3.0.0'
18
19
  gem.add_dependency 'mime-types'
19
20
 
20
21
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.9
1
+ 0.3.10
@@ -5,5 +5,5 @@ APPLICATION_API_KEY = 'fgK8Di4FYuRKtk2Xd12A' # your application's API key with r
5
5
 
6
6
  StorageRoom.authenticate(ACCOUNT_ID, APPLICATION_API_KEY)
7
7
 
8
- StorageRoom.server = "api.lvh.me:3000"
9
- # StorageRoom.server = "api.storageroomapp.com"
8
+ # StorageRoom.server = "api.lvh.me:3000"
9
+ StorageRoom.server = "api.storageroomapp.com"
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby -rubygems
2
+
3
+ require File.join(File.dirname(__FILE__), 'authentication')
4
+
5
+ class Guidebook < StorageRoom::Entry
6
+ before_create :log_before_create
7
+ after_create :log_after_create
8
+
9
+ before_save :log_before_save
10
+
11
+ before_destroy :log_before_destroy
12
+
13
+ def log_before_create
14
+ puts "Before create '#{title}'"
15
+ end
16
+
17
+ def log_after_create
18
+ puts "After create '#{title}'"
19
+ end
20
+
21
+ def log_before_save
22
+ puts "Before save '#{title}'"
23
+ end
24
+
25
+ def log_before_destroy
26
+ puts "Before destroy '#{title}'"
27
+ end
28
+ end
29
+
30
+ guidebook_collection = StorageRoom::Collection.find('4e1e9c234250712eba00005f')
31
+
32
+ guidebook = Guidebook.new(:title => 'Bar')
33
+
34
+ guidebook.save
35
+
36
+ guidebook.destroy
data/lib/storage_room.rb CHANGED
@@ -6,6 +6,7 @@ begin; require 'rubygems'; rescue LoadError; end
6
6
  require 'httparty'
7
7
  require 'mime/types'
8
8
  require 'base64'
9
+ require 'active_model'
9
10
  require 'active_support/all'
10
11
  require 'storage_room/extensions/const_defined'
11
12
  require 'storage_room/extensions/symbol'
@@ -5,6 +5,9 @@ module StorageRoom
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
8
+ self.send(:extend, ::ActiveModel::Callbacks)
9
+ self.send(:define_model_callbacks, :initialize_from_response_data)
10
+
8
11
  self.class_inheritable_accessor :attribute_options
9
12
  self.attribute_options ||= {}
10
13
  end
@@ -105,19 +108,21 @@ module StorageRoom
105
108
 
106
109
  # Iterate over the response data and initialize the attributes
107
110
  def initialize_from_response_data # :nodoc:
108
- self.class.attribute_options.each do |name, options|
109
- value = if options[:type] == :key
110
- self[name].blank? ? options[:default] : self[name]
111
- elsif options[:type] == :one
112
- hash = self[name.to_s]
113
- hash && hash['@type'] ? self.class.new_from_response_data(hash) : nil
114
- elsif options[:type] == :many
115
- response_data[name] && response_data[name].map{|hash| self.class.new_from_response_data(hash)} || []
116
- else
117
- raise "Invalid type: #{options[:type]}"
118
- end
111
+ _run_initialize_from_response_data_callbacks do
112
+ self.class.attribute_options.each do |name, options|
113
+ value = if options[:type] == :key
114
+ self[name].blank? ? options[:default] : self[name]
115
+ elsif options[:type] == :one
116
+ hash = self[name.to_s]
117
+ hash && hash['@type'] ? self.class.new_from_response_data(hash) : nil
118
+ elsif options[:type] == :many
119
+ response_data[name] && response_data[name].map{|hash| self.class.new_from_response_data(hash)} || []
120
+ else
121
+ raise "Invalid type: #{options[:type]}"
122
+ end
119
123
 
120
- send("#{name}=", value)
124
+ send("#{name}=", value)
125
+ end
121
126
  end
122
127
  end
123
128
 
@@ -6,12 +6,16 @@ module StorageRoom
6
6
  def add_to_entry_class(klass) # :nodoc:
7
7
  super
8
8
 
9
- collection
9
+ # collection
10
10
  end
11
11
 
12
12
  # The target collection of the association field
13
13
  def collection
14
14
  @collection ||= Collection.load(self.collection_url)
15
15
  end
16
+
17
+ def collection_loaded?
18
+ @collection ? true : false
19
+ end
16
20
  end
17
21
  end
@@ -26,7 +26,7 @@ module StorageRoom
26
26
  return nil if url.nil?
27
27
 
28
28
  if identity_map_on? && object = identity_map[url]
29
- StorageRoom.log("Loaded #{object} from identity map (load)")
29
+ StorageRoom.log("Loaded #{object} (#{url}) from identity map (load)")
30
30
  object
31
31
  else
32
32
  super
@@ -39,7 +39,7 @@ module StorageRoom
39
39
  object = url ? identity_map[url] : nil
40
40
 
41
41
  if object.present? && identity_map_on?
42
- StorageRoom.log("Loaded #{object} from identity map (new_from_response_data)")
42
+ StorageRoom.log("Loaded #{object} (#{url}) from identity map (new_from_response_data)")
43
43
  object.set_from_response_data(response_data)
44
44
  else
45
45
  object = super
@@ -1,6 +1,8 @@
1
1
  module StorageRoom
2
2
  # Abstract superclass for classes that can persist to the remote servers
3
3
  class Model < Resource
4
+ define_model_callbacks :create, :update, :save, :destroy
5
+
4
6
  attr_accessor :skip_webhooks
5
7
 
6
8
  class << self
@@ -62,23 +64,33 @@ module StorageRoom
62
64
  # Create a new model on the server
63
65
  def create
64
66
  return false unless new_record?
65
- httparty = self.class.post(self.class.index_path, :body => to_json, :query => query_parameters)
66
- handle_save_response(httparty)
67
+ _run_save_callbacks do
68
+ _run_create_callbacks do
69
+ httparty = self.class.post(self.class.index_path, :body => to_json, :query => query_parameters)
70
+ handle_save_response(httparty)
71
+ end
72
+ end
67
73
  end
68
74
 
69
75
  # Update an existing model on the server
70
76
  def update
71
77
  return false if new_record?
72
- httparty = self.class.put(self[:@url], :body => to_json, :query => query_parameters)
73
- handle_save_response(httparty)
78
+ _run_save_callbacks do
79
+ _run_update_callbacks do
80
+ httparty = self.class.put(self[:@url], :body => to_json, :query => query_parameters)
81
+ handle_save_response(httparty)
82
+ end
83
+ end
74
84
  end
75
85
 
76
86
  # Delete an existing model on the server
77
87
  def destroy
78
88
  return false if new_record?
79
89
 
80
- httparty = self.class.delete(self[:@url], :query => query_parameters)
81
- self.class.handle_critical_response_errors(httparty)
90
+ _run_destroy_callbacks do
91
+ httparty = self.class.delete(self[:@url], :query => query_parameters)
92
+ self.class.handle_critical_response_errors(httparty)
93
+ end
82
94
 
83
95
  true
84
96
  end
@@ -7,6 +7,7 @@ module StorageRoom
7
7
  many :fields
8
8
  many :webhook_definitions
9
9
 
10
+
10
11
  class << self
11
12
  def index_path # :nodoc:
12
13
  "#{Resource.base_uri}/collections"
@@ -56,6 +57,22 @@ module StorageRoom
56
57
  nil
57
58
  end
58
59
 
60
+ # All fields of type AssociationField
61
+ def association_fields
62
+ fields.select{|f| f.is_a?(AssociationField)}
63
+ end
64
+
65
+ # Load all Collections that are related to the current one through AssociationFields
66
+ def load_associated_collections
67
+ array = association_fields
68
+
69
+ if array.map{|f| f.collection_loaded?}.include?(false)
70
+ StorageRoom.log("Fetching associated collections for '#{name}'")
71
+ array.each{|f| f.collection}
72
+ end
73
+ end
74
+
75
+
59
76
  protected
60
77
  def initialize_from_response_data
61
78
  super
@@ -1,7 +1,9 @@
1
1
  module StorageRoom
2
2
  class Entry < Model
3
3
  class_inheritable_accessor :collection
4
-
4
+
5
+ before_initialize_from_response_data :load_associated_collections
6
+
5
7
  class << self
6
8
  def index_path # :nodoc:
7
9
  "#{collection[:@url]}/entries"
@@ -35,6 +37,7 @@ module StorageRoom
35
37
  end
36
38
  end
37
39
 
40
+
38
41
  # The collection of a entry
39
42
  def collection
40
43
  self.class.collection
@@ -48,6 +51,12 @@ module StorageRoom
48
51
  def id
49
52
  self[:@url] ? self[:@url].split('/').last : nil
50
53
  end
51
-
54
+
55
+ protected
56
+ # Fetch all associated Collections before the Entry is initialized from the JSON document
57
+ def load_associated_collections # :nodoc:
58
+ collection.try(:load_associated_collections)
59
+ end
60
+
52
61
  end
53
62
  end
@@ -3,6 +3,8 @@ module StorageRoom
3
3
  class Resource
4
4
  include HTTParty
5
5
  extend Plugins
6
+
7
+
6
8
 
7
9
  include Accessors
8
10
 
data/storage_room.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{storage_room}
8
- s.version = "0.3.9"
8
+ s.version = "0.3.10"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Sascha Konietzke"]
12
- s.date = %q{2011-07-29}
12
+ s.date = %q{2011-08-03}
13
13
  s.description = %q{StorageRoom is a CMS system for Mobile Applications (iPhone, Android, BlackBerry, ...). This library gives you an ActiveModel-like interface to your data.}
14
14
  s.email = %q{sascha@thriventures.com}
15
15
  s.extra_rdoc_files = [
@@ -27,6 +27,7 @@ Gem::Specification.new do |s|
27
27
  "examples/associations.rb",
28
28
  "examples/authentication.rb",
29
29
  "examples/backup_uploads_from_export.rb",
30
+ "examples/callbacks.rb",
30
31
  "examples/create_entry.rb",
31
32
  "examples/destroy_entry.rb",
32
33
  "examples/get_collections.rb",
@@ -135,12 +136,14 @@ Gem::Specification.new do |s|
135
136
  s.add_development_dependency(%q<webmock>, [">= 0"])
136
137
  s.add_runtime_dependency(%q<httparty>, [">= 0.6.1"])
137
138
  s.add_runtime_dependency(%q<activesupport>, [">= 3.0.0"])
139
+ s.add_runtime_dependency(%q<activemodel>, [">= 3.0.0"])
138
140
  s.add_runtime_dependency(%q<mime-types>, [">= 0"])
139
141
  else
140
142
  s.add_dependency(%q<rspec>, [">= 1.2.9"])
141
143
  s.add_dependency(%q<webmock>, [">= 0"])
142
144
  s.add_dependency(%q<httparty>, [">= 0.6.1"])
143
145
  s.add_dependency(%q<activesupport>, [">= 3.0.0"])
146
+ s.add_dependency(%q<activemodel>, [">= 3.0.0"])
144
147
  s.add_dependency(%q<mime-types>, [">= 0"])
145
148
  end
146
149
  else
@@ -148,6 +151,7 @@ Gem::Specification.new do |s|
148
151
  s.add_dependency(%q<webmock>, [">= 0"])
149
152
  s.add_dependency(%q<httparty>, [">= 0.6.1"])
150
153
  s.add_dependency(%q<activesupport>, [">= 3.0.0"])
154
+ s.add_dependency(%q<activemodel>, [">= 3.0.0"])
151
155
  s.add_dependency(%q<mime-types>, [">= 0"])
152
156
  end
153
157
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 3
8
- - 9
9
- version: 0.3.9
8
+ - 10
9
+ version: 0.3.10
10
10
  platform: ruby
11
11
  authors:
12
12
  - Sascha Konietzke
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-07-29 00:00:00 +02:00
17
+ date: 2011-08-03 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -76,7 +76,7 @@ dependencies:
76
76
  type: :runtime
77
77
  version_requirements: *id004
78
78
  - !ruby/object:Gem::Dependency
79
- name: mime-types
79
+ name: activemodel
80
80
  prerelease: false
81
81
  requirement: &id005 !ruby/object:Gem::Requirement
82
82
  none: false
@@ -84,10 +84,25 @@ dependencies:
84
84
  - - ">="
85
85
  - !ruby/object:Gem::Version
86
86
  segments:
87
+ - 3
87
88
  - 0
88
- version: "0"
89
+ - 0
90
+ version: 3.0.0
89
91
  type: :runtime
90
92
  version_requirements: *id005
93
+ - !ruby/object:Gem::Dependency
94
+ name: mime-types
95
+ prerelease: false
96
+ requirement: &id006 !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ segments:
102
+ - 0
103
+ version: "0"
104
+ type: :runtime
105
+ version_requirements: *id006
91
106
  description: StorageRoom is a CMS system for Mobile Applications (iPhone, Android, BlackBerry, ...). This library gives you an ActiveModel-like interface to your data.
92
107
  email: sascha@thriventures.com
93
108
  executables: []
@@ -108,6 +123,7 @@ files:
108
123
  - examples/associations.rb
109
124
  - examples/authentication.rb
110
125
  - examples/backup_uploads_from_export.rb
126
+ - examples/callbacks.rb
111
127
  - examples/create_entry.rb
112
128
  - examples/destroy_entry.rb
113
129
  - examples/get_collections.rb