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 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
@@ -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
- synchronize( options[:synchronize] )
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
- # on an individual ActiveRecord instance but it is intended for use on
7
- # multiple instances.
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
- def self.synchronize(instances, key=self.primary_key)
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
- instances.each_with_index do |instance, index|
19
- instance.clear_aggregation_cache
20
- instance.clear_association_cache
21
- instance.instance_variable_set '@attributes', fresh_instances[index].attributes
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: 61
5
- prerelease: false
4
+ hash: 51
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 9
9
- - 3
10
- version: 0.9.3
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.3.7
122
+ rubygems_version: 1.6.0
123
123
  signing_key:
124
124
  specification_version: 3
125
125
  summary: Extends ActiveRecord functionality.