HasRemote 0.1.6 → 0.1.7
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/HasRemote.gemspec +40 -42
- data/README.rdoc +9 -11
- data/VERSION +1 -1
- data/lib/has_remote.rb +41 -40
- data/spec/synchronization_spec.rb +11 -1
- metadata +20 -9
- data/.gitignore +0 -4
data/HasRemote.gemspec
CHANGED
@@ -1,72 +1,70 @@
|
|
1
1
|
# Generated by jeweler
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{HasRemote}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.7"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Sjoerd Andringa"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-12-28}
|
13
13
|
s.description = %q{Bind a remote ActiveResource object to your local ActiveRecord objects, delegate attributes and optionally cache remote attributes locally.}
|
14
14
|
s.email = %q{sjoerd.andringa@innovationfactory.eu}
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"README.rdoc",
|
17
|
-
|
17
|
+
"TODO"
|
18
18
|
]
|
19
19
|
s.files = [
|
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
|
-
"tasks/rails.rake"
|
20
|
+
"HasRemote.gemspec",
|
21
|
+
"MIT-LICENSE",
|
22
|
+
"README.rdoc",
|
23
|
+
"Rakefile",
|
24
|
+
"TODO",
|
25
|
+
"VERSION",
|
26
|
+
"generators/has_remote_migration/has_remote_migration_generator.rb",
|
27
|
+
"generators/has_remote_migration/templates/create_has_remote_synchronizations.erb",
|
28
|
+
"init.rb",
|
29
|
+
"lib/has_remote.rb",
|
30
|
+
"lib/has_remote/synchronizable.rb",
|
31
|
+
"lib/has_remote/synchronization.rb",
|
32
|
+
"lib/has_remote/tasks.rb",
|
33
|
+
"rails/init.rb",
|
34
|
+
"shoulda_macros/has_remote_macros.rb",
|
35
|
+
"spec/caching_spec.rb",
|
36
|
+
"spec/database.yml",
|
37
|
+
"spec/has_remote_spec.rb",
|
38
|
+
"spec/has_remote_spec/book.rb",
|
39
|
+
"spec/has_remote_spec/cheese.rb",
|
40
|
+
"spec/has_remote_spec/product.rb",
|
41
|
+
"spec/has_remote_spec/user.rb",
|
42
|
+
"spec/schema.rb",
|
43
|
+
"spec/spec_helper.rb",
|
44
|
+
"spec/synchronization_spec.rb",
|
45
|
+
"tasks/rails.rake"
|
47
46
|
]
|
48
47
|
s.homepage = %q{http://github.com/innovationfactory/has_remote}
|
49
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
50
48
|
s.require_paths = ["lib"]
|
51
|
-
s.rubygems_version = %q{1.3.
|
49
|
+
s.rubygems_version = %q{1.3.7}
|
52
50
|
s.summary = %q{Bind a remote ActiveResource object to your local ActiveRecord objects.}
|
53
51
|
s.test_files = [
|
54
52
|
"spec/caching_spec.rb",
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
53
|
+
"spec/has_remote_spec.rb",
|
54
|
+
"spec/has_remote_spec/book.rb",
|
55
|
+
"spec/has_remote_spec/cheese.rb",
|
56
|
+
"spec/has_remote_spec/product.rb",
|
57
|
+
"spec/has_remote_spec/user.rb",
|
58
|
+
"spec/schema.rb",
|
59
|
+
"spec/spec_helper.rb",
|
60
|
+
"spec/synchronization_spec.rb"
|
63
61
|
]
|
64
62
|
|
65
63
|
if s.respond_to? :specification_version then
|
66
64
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
67
65
|
s.specification_version = 3
|
68
66
|
|
69
|
-
if Gem::Version.new(Gem::
|
67
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
70
68
|
else
|
71
69
|
end
|
72
70
|
else
|
data/README.rdoc
CHANGED
@@ -22,6 +22,14 @@ And only if you require synchronization, run:
|
|
22
22
|
script/generate has_remote_migration
|
23
23
|
|
24
24
|
rake db:migrate
|
25
|
+
|
26
|
+
=== Links
|
27
|
+
|
28
|
+
[RDoc:] http://rdoc.info/projects/innovationfactory/has_remote
|
29
|
+
[Github:] http://github.com/innovationfactory/has_remote
|
30
|
+
|
31
|
+
[Simple example of how HasRemote simplifies your code:] http://gist.github.com/176335
|
32
|
+
[Simple API authentication with HasRemote:] http://gist.github.com/174497
|
25
33
|
|
26
34
|
=== Examples
|
27
35
|
|
@@ -127,13 +135,6 @@ To specify additional parameters to send with the request that fetches updated r
|
|
127
135
|
(If you've overridden the <tt>updated_remotes</tt> class method on one of your synchronizable models, then note that these parameters are
|
128
136
|
passed in as a hash to <tt>updated_remotes</tt> internally.)
|
129
137
|
|
130
|
-
=== Documentation
|
131
|
-
|
132
|
-
To generate RDocs for this plugin, from the has_remote directory run:
|
133
|
-
rake rdoc
|
134
|
-
or from your application's root directory, run:
|
135
|
-
rake doc:plugins:has_remote
|
136
|
-
|
137
138
|
=== Testing
|
138
139
|
|
139
140
|
To run the specs of the plugin, from the HasRemote directory run:
|
@@ -143,10 +144,7 @@ To run the specs of the plugin, from the HasRemote directory run:
|
|
143
144
|
|
144
145
|
=== More information & patches
|
145
146
|
|
146
|
-
|
147
|
-
- Simple API authentication with HasRemote: http://gist.github.com/174497
|
148
|
-
|
149
|
-
Questions, requests and patches can be directed to sjoerd.andringa[AT]innovationfactory[DOT]nl.
|
147
|
+
Questions, requests and patches can be directed to sjoerd.andringa[AT]innovationfactory[DOT]eu.
|
150
148
|
|
151
149
|
|
152
150
|
Copyright (c) 2009-2010 Innovation Factory.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.7
|
data/lib/has_remote.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# The main module for the has_remote plugin. Please see README for more information.
|
2
2
|
#
|
3
3
|
module HasRemote
|
4
|
-
|
4
|
+
|
5
5
|
def self.included(base) #:nodoc:
|
6
6
|
base.extend ClassMethods
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
# Returns an array of all models that have a remote.
|
10
10
|
#
|
11
11
|
def self.models
|
@@ -14,25 +14,25 @@ module HasRemote
|
|
14
14
|
|
15
15
|
@models ||= []
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
# Updates cached attributes, destroys deleted records and adds new records of all models that have a remote.
|
19
19
|
# Also see HasRemote::Synchronizable.
|
20
20
|
#
|
21
21
|
def self.synchronize!
|
22
22
|
models.each(&:synchronize!)
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
module ClassMethods
|
26
|
-
|
26
|
+
|
27
27
|
# Gives your local ActiveRecord model a remote proxy (ActiveResource::Base),
|
28
28
|
# which enables you to look for certain attributes remotely.
|
29
|
-
#
|
29
|
+
#
|
30
30
|
# ==== Options
|
31
|
-
#
|
31
|
+
#
|
32
32
|
# [:foreign_key] The name of the column used to store the id of the remote resource. Defaults to :remote_id.
|
33
33
|
# [:remote_primary_key] The name of the remote resource's primary key. Defaults to :id.
|
34
34
|
# [:site, :user, :password, ...] Basically all ActiveResource configuration settings are available,
|
35
|
-
# see http://api.rubyonrails.org/classes/ActiveResource/Base.html
|
35
|
+
# see http://api.rubyonrails.org/classes/ActiveResource/Base.html
|
36
36
|
# [:through] Optional custom ActiveResource class name to use for the proxy. If not set, a default class called
|
37
37
|
# "<ModelName>::Remote" will be created dynamically. *Note* that any ActiveResource
|
38
38
|
# configuration options will still be applied to this class.
|
@@ -59,7 +59,7 @@ module HasRemote
|
|
59
59
|
# remote.attribute :username
|
60
60
|
# remote.attribute :full_name, :local_cache => true
|
61
61
|
# remote.attribute :email_address, :as => :email
|
62
|
-
# end
|
62
|
+
# end
|
63
63
|
# end
|
64
64
|
#
|
65
65
|
# User.find(1).username
|
@@ -69,13 +69,13 @@ module HasRemote
|
|
69
69
|
unless options[:through] || self.const_defined?("Remote")
|
70
70
|
self.const_set("Remote", ActiveResource::Base.clone)
|
71
71
|
end
|
72
|
-
|
72
|
+
|
73
73
|
@remote_class = options[:through] ? options.delete(:through).constantize : self::Remote
|
74
|
-
|
74
|
+
|
75
75
|
@remote_foreign_key = options.delete(:foreign_key) || :remote_id
|
76
|
-
|
76
|
+
|
77
77
|
@remote_primary_key = options.delete(:remote_primary_key) || :id
|
78
|
-
|
78
|
+
|
79
79
|
# create extra class methods
|
80
80
|
class << self
|
81
81
|
attr_reader :remote_class
|
@@ -83,42 +83,42 @@ module HasRemote
|
|
83
83
|
attr_reader :remote_finder
|
84
84
|
attr_reader :remote_primary_key
|
85
85
|
attr_writer :remote_attribute_aliases
|
86
|
-
|
86
|
+
|
87
87
|
def remote_attributes # :nodoc:
|
88
88
|
@remote_attributes ||= []
|
89
89
|
end
|
90
|
-
|
90
|
+
|
91
91
|
def remote_attribute_aliases # :nodoc:
|
92
92
|
@remote_attribute_aliases ||= {}
|
93
93
|
end
|
94
|
-
|
94
|
+
|
95
95
|
include HasRemote::Synchronizable
|
96
96
|
end
|
97
|
-
|
97
|
+
|
98
98
|
# set ARes to look for correct resource (only if not manually specified)
|
99
99
|
unless options[:element_name] || @remote_class.element_name != "remote"
|
100
100
|
@remote_class.element_name = self.name.underscore.split('/').last
|
101
101
|
end
|
102
|
-
|
102
|
+
|
103
103
|
# setup ARes class with given options
|
104
104
|
options.each do |option, value|
|
105
|
-
@remote_class.send "#{option}=", value
|
105
|
+
@remote_class.send "#{option}=", value
|
106
106
|
end
|
107
|
-
|
107
|
+
|
108
108
|
attr_accessor :skip_update_cache
|
109
|
-
|
109
|
+
|
110
110
|
block.call( Config.new(self) ) if block_given?
|
111
|
-
|
111
|
+
|
112
112
|
include InstanceMethods
|
113
113
|
HasRemote.models << self
|
114
114
|
end
|
115
|
-
|
115
|
+
|
116
116
|
end
|
117
|
-
|
117
|
+
|
118
118
|
module InstanceMethods
|
119
|
-
|
119
|
+
|
120
120
|
# Returns the remote proxy for this record as an <tt>ActiveResource::Base</tt> object. Returns nil
|
121
|
-
# if foreign key is nil.
|
121
|
+
# if foreign key is nil.
|
122
122
|
#
|
123
123
|
# *Arguments*
|
124
124
|
#
|
@@ -131,7 +131,7 @@ module HasRemote
|
|
131
131
|
end
|
132
132
|
@remote
|
133
133
|
end
|
134
|
-
|
134
|
+
|
135
135
|
# Checks whether a remote proxy exists.
|
136
136
|
#
|
137
137
|
def has_remote?
|
@@ -140,14 +140,14 @@ module HasRemote
|
|
140
140
|
#
|
141
141
|
return !remote(true).nil? rescue false
|
142
142
|
end
|
143
|
-
|
143
|
+
|
144
144
|
# Synchronizes all locally cached remote attributes to this object and saves the object.
|
145
145
|
#
|
146
146
|
def update_cached_attributes!
|
147
147
|
update_cached_attributes
|
148
148
|
save!
|
149
149
|
end
|
150
|
-
|
150
|
+
|
151
151
|
# Synchronizes all locally cached remote attributes to this object, but does not save the object.
|
152
152
|
#
|
153
153
|
# Note that when the remote does no longer exist, all remote attributes will be
|
@@ -155,20 +155,21 @@ module HasRemote
|
|
155
155
|
#
|
156
156
|
def update_cached_attributes
|
157
157
|
unless self.skip_update_cache || self.class.cached_attributes.empty?
|
158
|
+
r = has_remote? ? remote : nil
|
158
159
|
self.class.cached_attributes.each do |remote_attr|
|
159
160
|
local_attr = self.class.remote_attribute_aliases[remote_attr] || remote_attr
|
160
|
-
write_attribute(local_attr,
|
161
|
+
write_attribute(local_attr, r.try(remote_attr))
|
161
162
|
end
|
162
163
|
end
|
163
164
|
end
|
164
|
-
|
165
|
+
|
165
166
|
end
|
166
|
-
|
167
|
+
|
167
168
|
class Config
|
168
169
|
def initialize(base) #:nodoc:
|
169
170
|
@base = base
|
170
171
|
end
|
171
|
-
|
172
|
+
|
172
173
|
# Defines a remote attribute. Adds a getter method on instances, which delegates to the remote object.
|
173
174
|
#
|
174
175
|
# *Options*
|
@@ -178,7 +179,7 @@ module HasRemote
|
|
178
179
|
# [:as] Optionally map remote attribute to this name.
|
179
180
|
#
|
180
181
|
# *Example*
|
181
|
-
#
|
182
|
+
#
|
182
183
|
# class User < ActiveRecord::Base
|
183
184
|
# has_remote :site => '...' do |remote|
|
184
185
|
# remote.attribute :name, :local_cache => true
|
@@ -188,10 +189,10 @@ module HasRemote
|
|
188
189
|
#
|
189
190
|
def attribute(attr_name, options = {})
|
190
191
|
method_name = options[:as] || attr_name
|
191
|
-
|
192
|
+
|
192
193
|
@base.remote_attributes << attr_name
|
193
194
|
@base.remote_attribute_aliases = @base.remote_attribute_aliases.merge(attr_name => method_name)
|
194
|
-
|
195
|
+
|
195
196
|
unless options[:local_cache]
|
196
197
|
@base.class_eval <<-RB
|
197
198
|
|
@@ -207,9 +208,9 @@ module HasRemote
|
|
207
208
|
else
|
208
209
|
@base.cached_attributes << attr_name
|
209
210
|
end
|
210
|
-
|
211
|
+
|
211
212
|
end
|
212
|
-
|
213
|
+
|
213
214
|
# Lets you specify custom finder logic to find the record's remote object.
|
214
215
|
# It takes a block which is passed in the id of the remote object.
|
215
216
|
#
|
@@ -228,7 +229,7 @@ module HasRemote
|
|
228
229
|
def finder(&block)
|
229
230
|
@base.instance_variable_set "@remote_finder", block
|
230
231
|
end
|
231
|
-
|
232
|
+
|
232
233
|
end
|
233
|
-
|
234
|
+
|
234
235
|
end
|
@@ -7,6 +7,16 @@ describe HasRemote::Synchronization do
|
|
7
7
|
it { should validate_presence_of(:model_name) }
|
8
8
|
it { should validate_presence_of(:last_record_updated_at) }
|
9
9
|
it { should validate_presence_of(:last_record_id) }
|
10
|
-
|
10
|
+
|
11
|
+
describe "named scope 'for'" do
|
12
|
+
before do
|
13
|
+
@user_synchronization = HasRemote::Synchronization.create! :model_name => 'User', :last_record_updated_at => 1.day.ago, :last_record_id => 1
|
14
|
+
@book_synchronization = HasRemote::Synchronization.create! :model_name => 'Book', :last_record_updated_at => 1.day.ago, :last_record_id => 2
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should return synchronization records scoped by model_name" do
|
18
|
+
HasRemote::Synchronization.for('User').should == [@user_synchronization]
|
19
|
+
end
|
20
|
+
end
|
11
21
|
|
12
22
|
end
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: HasRemote
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 21
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 7
|
10
|
+
version: 0.1.7
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Sjoerd Andringa
|
@@ -9,7 +15,7 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date: 2010-
|
18
|
+
date: 2010-12-28 00:00:00 +01:00
|
13
19
|
default_executable:
|
14
20
|
dependencies: []
|
15
21
|
|
@@ -23,7 +29,6 @@ extra_rdoc_files:
|
|
23
29
|
- README.rdoc
|
24
30
|
- TODO
|
25
31
|
files:
|
26
|
-
- .gitignore
|
27
32
|
- HasRemote.gemspec
|
28
33
|
- MIT-LICENSE
|
29
34
|
- README.rdoc
|
@@ -55,36 +60,42 @@ homepage: http://github.com/innovationfactory/has_remote
|
|
55
60
|
licenses: []
|
56
61
|
|
57
62
|
post_install_message:
|
58
|
-
rdoc_options:
|
59
|
-
|
63
|
+
rdoc_options: []
|
64
|
+
|
60
65
|
require_paths:
|
61
66
|
- lib
|
62
67
|
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
63
69
|
requirements:
|
64
70
|
- - ">="
|
65
71
|
- !ruby/object:Gem::Version
|
72
|
+
hash: 3
|
73
|
+
segments:
|
74
|
+
- 0
|
66
75
|
version: "0"
|
67
|
-
version:
|
68
76
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
|
+
none: false
|
69
78
|
requirements:
|
70
79
|
- - ">="
|
71
80
|
- !ruby/object:Gem::Version
|
81
|
+
hash: 3
|
82
|
+
segments:
|
83
|
+
- 0
|
72
84
|
version: "0"
|
73
|
-
version:
|
74
85
|
requirements: []
|
75
86
|
|
76
87
|
rubyforge_project:
|
77
|
-
rubygems_version: 1.3.
|
88
|
+
rubygems_version: 1.3.7
|
78
89
|
signing_key:
|
79
90
|
specification_version: 3
|
80
91
|
summary: Bind a remote ActiveResource object to your local ActiveRecord objects.
|
81
92
|
test_files:
|
82
93
|
- spec/caching_spec.rb
|
94
|
+
- spec/has_remote_spec.rb
|
83
95
|
- spec/has_remote_spec/book.rb
|
84
96
|
- spec/has_remote_spec/cheese.rb
|
85
97
|
- spec/has_remote_spec/product.rb
|
86
98
|
- spec/has_remote_spec/user.rb
|
87
|
-
- spec/has_remote_spec.rb
|
88
99
|
- spec/schema.rb
|
89
100
|
- spec/spec_helper.rb
|
90
101
|
- spec/synchronization_spec.rb
|
data/.gitignore
DELETED