active_remote 1.6.1 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0b484c875f2b7f6e8dd9b3ba72d802c80ebd923c
4
- data.tar.gz: 29194830e6f79902050b17ce78c7494b56cfce85
3
+ metadata.gz: a53038e5bd4f39ffbba6356eaeeb8de9c55ee2aa
4
+ data.tar.gz: 694f516e1adb22e5fd3ed9c68395b6081a54d389
5
5
  SHA512:
6
- metadata.gz: 0664c1c11685b5260104c8f0eefc96bda16195b69e0aa8de185a4540f854a8ea1b273e1ea8b5e18fbd5b24951c84078ed88e03f86eb0aacf1686cf44395cf1d7
7
- data.tar.gz: 1169cb3e752f32648903e8e8d3d1c97e3264230b73bfabc7a4870200f58ad3d9aa385df0193edaac9795894221ebcedff63bb3df2ac26b60f901a6a91c22b824
6
+ metadata.gz: 179ff3825b682860f3600cf90735a783c49f175f764ed56779d859b230da021961f7124faac2561fbc029d0ee9924f37c00532b2190a11d4495f1e5525c25fd9
7
+ data.tar.gz: 1f3d111e0cc746926899f9aba30f2c82e32caeb4eddca8250debdcf1830c877588d4e0c29cc3a36352e253c98562d21ea5ee34de1ed8aa8831ebbef34116f8f8
data/.gitignore CHANGED
@@ -3,6 +3,7 @@
3
3
  .DS_Store
4
4
  .bundle
5
5
  .config
6
+ .ruby-*
6
7
  .rvmrc
7
8
  .yardoc
8
9
  .idea
@@ -20,6 +20,7 @@ Gem::Specification.new do |s|
20
20
  # Dependencies
21
21
  #
22
22
  s.add_dependency "active_attr"
23
+ s.add_dependency "activesupport"
23
24
  s.add_dependency "protobuf", ">= 2.0"
24
25
 
25
26
  ##
@@ -1,15 +1,29 @@
1
1
  require 'active_attr'
2
2
  require 'active_model'
3
+ require 'protobuf'
4
+
3
5
  require 'active_support/core_ext/array'
4
6
  require 'active_support/core_ext/hash'
5
7
  require 'active_support/inflector'
6
8
  require 'active_support/json'
7
9
 
8
- require 'core_ext/date_time'
9
- require 'core_ext/date'
10
- require 'core_ext/integer'
10
+ require 'active_remote/core_ext/date_time'
11
+ require 'active_remote/core_ext/date'
12
+ require 'active_remote/core_ext/integer'
11
13
 
12
14
  require 'active_remote/base'
15
+ require 'active_remote/config'
13
16
  require 'active_remote/errors'
14
17
 
15
18
  require 'active_remote/version'
19
+
20
+ module ActiveRemote
21
+ def self.config
22
+ @config ||= ::ActiveRemote::Config.new
23
+ end
24
+
25
+ # Initialize the config
26
+ config
27
+ end
28
+
29
+ require 'active_remote/railtie' if defined?(Rails)
@@ -6,7 +6,7 @@ module ActiveRemote
6
6
  name = name.to_s
7
7
 
8
8
  if respond_to? name
9
- @attributes[name]
9
+ attribute(name)
10
10
  else
11
11
  raise ::ActiveAttr::UnknownAttributeError, "unknown attribute: #{name}"
12
12
  end
@@ -19,7 +19,7 @@ module ActiveRemote
19
19
  name = name.to_s
20
20
 
21
21
  if respond_to? "#{name}="
22
- @attributes[name] = typecast_attribute(_attribute_typecaster(name), value)
22
+ __send__("attribute=", name, value)
23
23
  else
24
24
  raise ::ActiveAttr::UnknownAttributeError, "unknown attribute: #{name}"
25
25
  end
@@ -1,6 +1,7 @@
1
1
  require 'active_remote/association'
2
2
  require 'active_remote/attributes'
3
3
  require 'active_remote/bulk'
4
+ require 'active_remote/config'
4
5
  require 'active_remote/dirty'
5
6
  require 'active_remote/dsl'
6
7
  require 'active_remote/integration'
@@ -104,7 +104,12 @@ module ActiveRemote
104
104
  #
105
105
  def parse_records(*records)
106
106
  records.flatten!
107
- records.collect!(&:to_hash)
107
+
108
+ if records.first.respond_to?(:attributes)
109
+ records.collect!(&:attributes)
110
+ else
111
+ records.collect!(&:to_hash)
112
+ end
108
113
 
109
114
  return records.first if records.first.has_key?(:records)
110
115
 
@@ -0,0 +1,23 @@
1
+ require 'active_support/ordered_options'
2
+
3
+ module ActiveRemote
4
+ class Config < ::ActiveSupport::OrderedOptions
5
+
6
+ def initialize(options = {})
7
+ super
8
+
9
+ self.default_cache_key_updated_at = false
10
+ self.include_root_in_json = true
11
+ end
12
+
13
+ def default_cache_key_updated_at?
14
+ self[:default_cache_key_updated_at]
15
+ end
16
+
17
+ def include_root_in_json=(true_or_false)
18
+ self[:include_root_in_json] = !!true_or_false
19
+ ::ActiveRemote::Base.include_root_in_json = self[:include_root_in_json]
20
+ end
21
+
22
+ end
23
+ end
@@ -46,7 +46,7 @@ module ActiveRemote
46
46
  @publishable_attributes
47
47
  end
48
48
 
49
- # Set the RPC service class directly. By default, ActiveRemove determines
49
+ # Set the RPC service class directly. By default, ActiveRemote determines
50
50
  # the RPC service by constantizing the namespace and service name.
51
51
  #
52
52
  # ====Examples
@@ -34,14 +34,14 @@ module ActiveRemote
34
34
  # ==== Examples
35
35
  #
36
36
  # Product.new.cache_key # => "products/new"
37
- # Product.search(:guid => "derp-5").cache_key # => "products/derp-5" (updated_at not available)
38
- # Person.search(:guid => "derp-5").cache_key # => "people/derp-5-20071224150000" (updated_at available)
37
+ # Person.search(:guid => "derp-5").cache_key # => "people/derp-5-20071224150000" (include updated_at)
38
+ # Product.search(:guid => "derp-5").cache_key # => "products/derp-5"
39
39
  #
40
40
  def cache_key
41
41
  case
42
42
  when new_record? then
43
43
  "#{self.class.name.underscore}/new"
44
- when timestamp = self[:updated_at] then
44
+ when ::ActiveRemote.config.default_cache_key_updated_at? && (timestamp = self[:updated_at]) then
45
45
  timestamp = timestamp.utc.to_s(self.class.cache_timestamp_format)
46
46
  "#{self.class.name.underscore}/#{self.to_param}-#{timestamp}"
47
47
  else
@@ -10,7 +10,7 @@ module ActiveRemote
10
10
 
11
11
  # Allow users to create callbacks around a `save` call.
12
12
  #
13
- define_model_callbacks :save
13
+ define_model_callbacks :save, :create, :update
14
14
 
15
15
  # Before a save occurs, ensure that we
16
16
  # clear out the errors list.
@@ -75,7 +75,7 @@ module ActiveRemote
75
75
  #
76
76
  def delete
77
77
  raise ReadOnlyRemoteRecord if readonly?
78
- execute(:delete, @attributes.slice("guid"))
78
+ execute(:delete, "guid" => read_attribute("guid"))
79
79
 
80
80
  return success? ? freeze : false
81
81
  end
@@ -98,7 +98,7 @@ module ActiveRemote
98
98
  #
99
99
  def destroy
100
100
  raise ReadOnlyRemoteRecord if readonly?
101
- execute(:destroy, @attributes.slice("guid"))
101
+ execute(:destroy, "guid" => read_attribute("guid"))
102
102
 
103
103
  return success? ? freeze : false
104
104
  end
@@ -197,16 +197,18 @@ module ActiveRemote
197
197
  # errors from the response.
198
198
  #
199
199
  def create
200
- # Use the getter here so we get the type casting.
201
- new_attributes = attributes
202
- new_attributes.delete("guid")
200
+ run_callbacks :create do
201
+ # Use the getter here so we get the type casting.
202
+ new_attributes = attributes
203
+ new_attributes.delete("guid")
203
204
 
204
- execute(:create, new_attributes)
205
+ execute(:create, new_attributes)
205
206
 
206
- assign_attributes(last_response.to_hash)
207
- add_errors_from_response
207
+ assign_attributes(last_response.to_hash)
208
+ add_errors_from_response
208
209
 
209
- success?
210
+ success?
211
+ end
210
212
  end
211
213
 
212
214
  # Deterines whether the record should be created or updated. New records
@@ -223,17 +225,19 @@ module ActiveRemote
223
225
  # (plus :guid) will be updated. Defaults to all attributes.
224
226
  #
225
227
  def update(attribute_names = @attributes.keys)
226
- # Use the getter here so we get the type casting.
227
- updated_attributes = attributes
228
- updated_attributes.slice!(*attribute_names)
229
- updated_attributes.merge!("guid" => self[:guid])
228
+ run_callbacks :update do
229
+ # Use the getter here so we get the type casting.
230
+ updated_attributes = attributes
231
+ updated_attributes.slice!(*attribute_names)
232
+ updated_attributes.merge!("guid" => self[:guid])
230
233
 
231
- execute(:update, updated_attributes)
234
+ execute(:update, updated_attributes)
232
235
 
233
- assign_attributes(last_response.to_hash)
234
- add_errors_from_response
236
+ assign_attributes(last_response.to_hash)
237
+ add_errors_from_response
235
238
 
236
- success?
239
+ success?
240
+ end
237
241
  end
238
242
  end
239
243
  end
@@ -6,7 +6,7 @@ module ActiveRemote
6
6
  keys = _publishable_attributes_or_attribute_keys
7
7
 
8
8
  attributes_hash = keys.inject({}) do |publishable_hash, key|
9
- value = respond_to?(key) ? __send__(key) : @attributes[key]
9
+ value = respond_to?(key) ? __send__(key) : read_attribute(key)
10
10
 
11
11
  publishable_hash[key] = case
12
12
  when value.respond_to?(:map) then
@@ -0,0 +1,5 @@
1
+ module ActiveRemote
2
+ class Railtie < ::Rails::Railtie
3
+ config.active_remote = ::ActiveRemote.config
4
+ end
5
+ end
@@ -1,5 +1,3 @@
1
- require 'protobuf_extensions/base_field'
2
-
3
1
  module ActiveRemote
4
2
  module Serializers
5
3
  module Protobuf
@@ -1,3 +1,3 @@
1
1
  module ActiveRemote
2
- VERSION = "1.6.1"
2
+ VERSION = "1.7.0"
3
3
  end
@@ -42,12 +42,24 @@ describe ActiveRemote::Bulk do
42
42
 
43
43
  describe ".parse_records" do
44
44
  let(:records) { [ Hash.new ] }
45
+ let(:attribute_record) {
46
+ record = double(Hash)
47
+ record.stub(:attributes) { {} }
48
+ record
49
+ }
50
+ let(:records) { [ Hash.new ] }
45
51
 
46
52
  it "preps records to be built into a bulk request" do
47
53
  parsed_records = { :records => records }
48
54
  Tag.parse_records(records).should eq parsed_records
49
55
  end
50
56
 
57
+ it "preps records to be built into a bulk request (prioritizing :attributes over :to_hash)" do
58
+ attribute_record.should_receive(:attributes)
59
+ parsed_records = { :records => [ {} ] }
60
+ Tag.parse_records([ attribute_record ]).should eq parsed_records
61
+ end
62
+
51
63
  context "when given a bulk message" do
52
64
  let(:records) { [ tag.to_hash ] }
53
65
  let(:tag) { Generic::Remote::Tag.new }
@@ -71,4 +83,4 @@ describe ActiveRemote::Bulk do
71
83
  Tag.update_all(records)
72
84
  end
73
85
  end
74
- end
86
+ end
@@ -28,10 +28,16 @@ describe ::ActiveRemote::Integration do
28
28
  end
29
29
 
30
30
  it "adds the 'updated_at' attribute to the cache_key if updated_at is present" do
31
+ ::ActiveRemote.config.default_cache_key_updated_at = true
31
32
  twenty_o_one_one = subject[:updated_at] = DateTime.new(2001, 01, 01)
32
33
  subject.should_receive(:new_record?).and_return(false)
33
34
  subject.cache_key.should eq("tag/#{guid}-#{twenty_o_one_one.to_s(:number)}")
34
35
  subject[:updated_at] = nil
36
+ ::ActiveRemote.config.default_cache_key_updated_at = false
37
+ end
38
+
39
+ it "defaults the cache updated_at to false" do
40
+ ::ActiveRemote.config.default_cache_key_updated_at?.should be_false
35
41
  end
36
42
  end
37
43
  end
@@ -9,6 +9,12 @@ describe ActiveRemote::Persistence do
9
9
  before { Tag.any_instance.stub(:execute) }
10
10
  after { Tag.any_instance.unstub(:execute) }
11
11
 
12
+ it "runs create callbacks" do
13
+ Tag.any_instance.should_receive(:after_create_callback)
14
+ Tag.create(:name => 'foo')
15
+ end
16
+
17
+
12
18
  it "initializes and saves a new record" do
13
19
  Tag.any_instance.should_receive(:save)
14
20
  Tag.create(:name => 'foo')
@@ -170,7 +176,7 @@ describe ActiveRemote::Persistence do
170
176
  before { subject.stub(:execute) }
171
177
  after { subject.unstub(:execute) }
172
178
 
173
- it "runs callbacks" do
179
+ it "runs save callbacks" do
174
180
  subject.should_receive(:run_callbacks).with(:save)
175
181
  subject.save
176
182
  end
@@ -257,6 +263,15 @@ describe ActiveRemote::Persistence do
257
263
  describe "#update_attributes" do
258
264
  let(:attributes) { HashWithIndifferentAccess.new(:name => 'bar') }
259
265
 
266
+ before { Tag.any_instance.stub(:execute) }
267
+ after { Tag.any_instance.unstub(:execute) }
268
+
269
+ it "runs update callbacks" do
270
+ tag = Tag.new({:guid => "123"})
271
+ tag.should_receive(:after_update_callback)
272
+ tag.update_attributes({})
273
+ end
274
+
260
275
  before { subject.stub(:save) }
261
276
  after { subject.unstub(:save) }
262
277
 
@@ -7,32 +7,71 @@ describe ActiveRemote::Serializers::JSON do
7
7
 
8
8
  subject { Tag.new(attributes) }
9
9
 
10
- context "when options are nil" do
11
- it "substitutes an empty hash" do
12
- subject.as_json(nil).should eq serializable_attributes
10
+ context "with roots in json" do
11
+ context "when options are nil" do
12
+ it "substitutes an empty hash" do
13
+ subject.as_json(nil).should eq serializable_attributes
14
+ end
13
15
  end
14
- end
15
16
 
16
- it "accepts standard JSON options" do
17
- subject.as_json(:root => false).should eq attributes.stringify_keys
18
- end
17
+ it "accepts standard JSON options" do
18
+ subject.as_json(:root => false).should eq attributes.stringify_keys
19
+ end
19
20
 
20
- context "with publishable attributes defined" do
21
- let(:expected_json) { { :tag => attributes.slice(:name) }.to_json }
21
+ context "with publishable attributes defined" do
22
+ let(:expected_json) { { :tag => attributes.slice(:name) }.to_json }
22
23
 
23
- before { Tag.attr_publishable :name }
24
- after { reset_publishable_attributes(Tag) }
24
+ before { Tag.attr_publishable :name }
25
+ after { reset_publishable_attributes(Tag) }
25
26
 
26
- it "serializes to JSON with only the publishable attributes" do
27
- subject.to_json.should eq expected_json
27
+ it "serializes to JSON with only the publishable attributes" do
28
+ subject.to_json.should eq expected_json
29
+ end
30
+ end
31
+
32
+ context "without publishable attributes defined" do
33
+ let(:expected_json) { { :tag => attributes }.to_json }
34
+
35
+ it "serializes to JSON" do
36
+ subject.to_json.should eq expected_json
37
+ end
28
38
  end
29
39
  end
30
40
 
31
- context "without publishable attributes defined" do
32
- let(:expected_json) { { :tag => attributes }.to_json }
41
+ context "without roots in json" do
42
+ let(:serializable_attributes) { attributes.stringify_keys }
43
+
44
+ before(:each) do
45
+ ::ActiveRemote.config.include_root_in_json = false
46
+ end
47
+
48
+ after(:each) do
49
+ ::ActiveRemote.config.include_root_in_json = true
50
+ end
51
+
52
+ context "when options are nil" do
53
+ it "substitutes an empty hash" do
54
+ subject.as_json(nil).should eq serializable_attributes
55
+ end
56
+ end
57
+
58
+ context "with publishable attributes defined" do
59
+ let(:expected_json) { attributes.slice(:name).to_json }
60
+
61
+ before { Tag.attr_publishable :name }
62
+ after { reset_publishable_attributes(Tag) }
63
+
64
+ it "serializes to JSON with only the publishable attributes" do
65
+ subject.to_json.should eq expected_json
66
+ end
67
+ end
68
+
69
+ context "without publishable attributes defined" do
70
+ let(:expected_json) { attributes.to_json }
33
71
 
34
- it "serializes to JSON" do
35
- subject.to_json.should eq expected_json
72
+ it "serializes to JSON" do
73
+ subject.to_json.should eq expected_json
74
+ end
36
75
  end
37
76
  end
38
77
  end
@@ -10,4 +10,12 @@ class Tag < ::ActiveRemote::Base
10
10
  attribute :name
11
11
  attribute :updated_at
12
12
 
13
+ after_update :after_update_callback
14
+ after_create :after_create_callback
15
+
16
+ def after_create_callback
17
+ end
18
+
19
+ def after_update_callback
20
+ end
13
21
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_remote
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.1
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Hutchison
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-08-31 00:00:00.000000000 Z
11
+ date: 2013-11-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: active_attr
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: protobuf
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -143,22 +157,23 @@ files:
143
157
  - lib/active_remote/attributes.rb
144
158
  - lib/active_remote/base.rb
145
159
  - lib/active_remote/bulk.rb
160
+ - lib/active_remote/config.rb
161
+ - lib/active_remote/core_ext/date.rb
162
+ - lib/active_remote/core_ext/date_time.rb
163
+ - lib/active_remote/core_ext/integer.rb
146
164
  - lib/active_remote/dirty.rb
147
165
  - lib/active_remote/dsl.rb
148
166
  - lib/active_remote/errors.rb
149
167
  - lib/active_remote/integration.rb
150
168
  - lib/active_remote/persistence.rb
151
169
  - lib/active_remote/publication.rb
170
+ - lib/active_remote/railtie.rb
152
171
  - lib/active_remote/rpc.rb
153
172
  - lib/active_remote/search.rb
154
173
  - lib/active_remote/serialization.rb
155
174
  - lib/active_remote/serializers/json.rb
156
175
  - lib/active_remote/serializers/protobuf.rb
157
176
  - lib/active_remote/version.rb
158
- - lib/core_ext/date.rb
159
- - lib/core_ext/date_time.rb
160
- - lib/core_ext/integer.rb
161
- - lib/protobuf_extensions/base_field.rb
162
177
  - spec/core_ext/date_time_spec.rb
163
178
  - spec/lib/active_remote/association_spec.rb
164
179
  - spec/lib/active_remote/base_spec.rb
@@ -211,41 +226,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
211
226
  version: '0'
212
227
  requirements: []
213
228
  rubyforge_project:
214
- rubygems_version: 2.0.6
229
+ rubygems_version: 2.0.3
215
230
  signing_key:
216
231
  specification_version: 4
217
232
  summary: Active Record for your platform
218
- test_files:
219
- - spec/core_ext/date_time_spec.rb
220
- - spec/lib/active_remote/association_spec.rb
221
- - spec/lib/active_remote/base_spec.rb
222
- - spec/lib/active_remote/bulk_spec.rb
223
- - spec/lib/active_remote/dirty_spec.rb
224
- - spec/lib/active_remote/dsl_spec.rb
225
- - spec/lib/active_remote/integration_spec.rb
226
- - spec/lib/active_remote/persistence_spec.rb
227
- - spec/lib/active_remote/publication_spec.rb
228
- - spec/lib/active_remote/rpc_spec.rb
229
- - spec/lib/active_remote/search_spec.rb
230
- - spec/lib/active_remote/serialization_spec.rb
231
- - spec/lib/active_remote/serializers/json_spec.rb
232
- - spec/lib/active_remote/serializers/protobuf_spec.rb
233
- - spec/spec_helper.rb
234
- - spec/support/definitions/author.proto
235
- - spec/support/definitions/post.proto
236
- - spec/support/definitions/support/protobuf/category.proto
237
- - spec/support/definitions/support/protobuf/error.proto
238
- - spec/support/definitions/tag.proto
239
- - spec/support/helpers.rb
240
- - spec/support/models.rb
241
- - spec/support/models/author.rb
242
- - spec/support/models/category.rb
243
- - spec/support/models/message_with_options.rb
244
- - spec/support/models/post.rb
245
- - spec/support/models/tag.rb
246
- - spec/support/protobuf.rb
247
- - spec/support/protobuf/author.pb.rb
248
- - spec/support/protobuf/category.pb.rb
249
- - spec/support/protobuf/error.pb.rb
250
- - spec/support/protobuf/post.pb.rb
251
- - spec/support/protobuf/tag.pb.rb
233
+ test_files: []
@@ -1,18 +0,0 @@
1
- require 'protobuf'
2
-
3
- # A couple of helper fields.
4
- # Might make sense to create a patch for Protobuf.
5
- #
6
- Protobuf::Field::BaseField.class_eval do
7
- unless respond_to?(:enum?)
8
- def enum?
9
- kind_of?(Protobuf::Field::EnumField)
10
- end
11
- end
12
-
13
- unless respond_to?(:message?)
14
- def message?
15
- kind_of?(Protobuf::Field::MessageField)
16
- end
17
- end
18
- end