ar-extensions 0.9.3 → 0.9.4
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/README +7 -0
- data/lib/ar-extensions/import.rb +8 -1
- data/lib/ar-extensions/synchronize.rb +38 -12
- metadata +5 -5
data/README
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
*ar-extensions is not compatible and is not being developed for Rails 3. Please use the activerecord-import gem which supports the same interface.*
|
2
|
+
|
1
3
|
LICENSE
|
2
4
|
----------
|
3
5
|
This is licensed under the ruby license.
|
@@ -10,6 +12,11 @@ Email: zach.dennis@gmail.com
|
|
10
12
|
- For project information and feedback please consult http://rubyforge.org/projects/arext/
|
11
13
|
- For release information please see below
|
12
14
|
|
15
|
+
ActiveRecord::Extensions 0.9.4
|
16
|
+
------------------------------
|
17
|
+
April 6, 2011
|
18
|
+
- Added :synchronize_keys option for import which allows people to synchronize on specified fields besides the primary key. Note these fields should be unique
|
19
|
+
|
13
20
|
ActiveRecord::Extensions 0.9.0, 0.9.1
|
14
21
|
------------------------------
|
15
22
|
April 17, 2009
|
data/lib/ar-extensions/import.rb
CHANGED
@@ -123,6 +123,11 @@ class ActiveRecord::Base
|
|
123
123
|
# BlogPost.import posts, :synchronize=>[ post ]
|
124
124
|
# puts post.author_name # => 'yoda'
|
125
125
|
#
|
126
|
+
# # Example synchronizing unsaved/new instances in memory by using a uniqued imported field
|
127
|
+
# posts = [BlogPost.new(:title => "Foo"), BlogPost.new(:title => "Bar")]
|
128
|
+
# BlogPost.import posts, :synchronize => posts
|
129
|
+
# puts posts.first.new_record? # => false
|
130
|
+
#
|
126
131
|
# == On Duplicate Key Update (MySQL only)
|
127
132
|
#
|
128
133
|
# The :on_duplicate_key_update option can be either an Array or a Hash.
|
@@ -206,8 +211,10 @@ class ActiveRecord::Base
|
|
206
211
|
num_inserts = import_without_validations_or_callbacks( column_names, array_of_attributes, options )
|
207
212
|
OpenStruct.new :failed_instances=>[], :num_inserts=>num_inserts
|
208
213
|
end
|
214
|
+
|
209
215
|
if options[:synchronize]
|
210
|
-
|
216
|
+
sync_keys = options[:synchronize_keys] || [self.primary_key]
|
217
|
+
synchronize( options[:synchronize], sync_keys)
|
211
218
|
end
|
212
219
|
|
213
220
|
return_obj.num_inserts = 0 if return_obj.num_inserts.nil?
|
@@ -2,28 +2,54 @@ module ActiveRecord # :nodoc:
|
|
2
2
|
class Base # :nodoc:
|
3
3
|
|
4
4
|
# Synchronizes the passed in ActiveRecord instances with data
|
5
|
-
# from the database. This is like calling reload
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
5
|
+
# from the database. This is like calling reload on an individual
|
6
|
+
# ActiveRecord instance but it is intended for use on multiple instances.
|
7
|
+
#
|
9
8
|
# This uses one query for all instance updates and then updates existing
|
10
9
|
# instances rather sending one query for each instance
|
11
|
-
|
10
|
+
#
|
11
|
+
# == Examples
|
12
|
+
# # Synchronizing existing models (ie: models with an id)
|
13
|
+
# posts = Post.find_by_author("Zach")
|
14
|
+
# Post.import [:id, :author], [[posts.first.id, "Zachary"]], :synchronize => posts
|
15
|
+
# posts.first.author # => "Zachary" instead of Zach
|
16
|
+
#
|
17
|
+
# # Synchronizing new/unsaved models by using a unique column to perform the sync
|
18
|
+
# posts = [Post.new(:author => "Zach")]
|
19
|
+
# posts.first.new_record? # => true
|
20
|
+
# posts.first.id # => nil
|
21
|
+
# Post.import posts, :synchronize => posts
|
22
|
+
# posts.first.new_record? # => false
|
23
|
+
# posts.first.id # => 1
|
24
|
+
#
|
25
|
+
def self.synchronize(instances, keys=[self.primary_key])
|
12
26
|
return if instances.empty?
|
27
|
+
|
28
|
+
conditions = {}
|
29
|
+
order = ""
|
30
|
+
|
31
|
+
key_values = keys.map { |key| instances.map(&"#{key}".to_sym) }
|
32
|
+
keys.zip(key_values).each { |key, values| conditions[key] = values }
|
33
|
+
order = keys.map{ |key| "#{key} ASC" }.join(",")
|
13
34
|
|
14
|
-
keys = instances.map(&"#{key}".to_sym)
|
15
35
|
klass = instances.first.class
|
16
|
-
fresh_instances = klass.find( :all, :conditions=>{ key=>keys }, :order=>"#{key} ASC" )
|
17
36
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
37
|
+
fresh_instances = klass.find( :all, :conditions=>conditions, :order=>order )
|
38
|
+
instances.each do |instance|
|
39
|
+
matched_instance = fresh_instances.detect do |fresh_instance|
|
40
|
+
keys.all?{ |key| fresh_instance.send(key) == instance.send(key) }
|
41
|
+
end
|
42
|
+
|
43
|
+
if matched_instance
|
44
|
+
instance.clear_aggregation_cache
|
45
|
+
instance.clear_association_cache
|
46
|
+
instance.instance_variable_set '@attributes', matched_instance.attributes
|
47
|
+
end
|
22
48
|
end
|
23
49
|
end
|
24
50
|
|
25
51
|
# See ActiveRecord::ConnectionAdapters::AbstractAdapter.synchronize
|
26
|
-
def synchronize(instances, key=ActiveRecord::Base.primary_key)
|
52
|
+
def synchronize(instances, key=[ActiveRecord::Base.primary_key])
|
27
53
|
self.class.synchronize(instances, key)
|
28
54
|
end
|
29
55
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ar-extensions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 51
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 9
|
9
|
-
-
|
10
|
-
version: 0.9.
|
9
|
+
- 4
|
10
|
+
version: 0.9.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Zach Dennis
|
@@ -119,7 +119,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
119
119
|
requirements: []
|
120
120
|
|
121
121
|
rubyforge_project: arext
|
122
|
-
rubygems_version: 1.
|
122
|
+
rubygems_version: 1.6.0
|
123
123
|
signing_key:
|
124
124
|
specification_version: 3
|
125
125
|
summary: Extends ActiveRecord functionality.
|